本文实例为大家分享了android水平循环滚动控件的具体代码,供大家参考,具体内容如下
CycleScrollView.java
package com.example.test;
import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
@SuppressWarnings("deprecation")
public class CycleScrollView extends ViewGroup implements onGestureListener {
static final String TAG = "CycleScrollView";
Context mContext;
public static final long SCROLL_VELOCITY = 50;
public static final int SCROLL_OFFSET = -1;
public static final long TOUCH_DELAYMILLIS = 2000;
public static final int FLING_DURATION = 2000;
public static final int MAX_VELOCITY_X = 1000;
private GestureDetector detector;
private Handler mHandler;
private Scroller mScroller;
private CycleScrollAdapter mAdapter;
private onItemClickListener mOnItemClickListener;
private int mPreIndex;
private int mCurrentIndex;
private int mNextIndex;
private View mCurrentView;
private View mPreView;
private View mNextView;
private float mLastMotionX;
// The reLayout is false can not invoke onLayout.
private boolean reLayout = false;
// If the item count more than screen that can scroll.
private boolean canScroll = false;
// A flag for switch current view.
private boolean mCurrentViewAtLeft = true;
// Fling distance.
private int mFlingX = 0;
private boolean isMoveAction = false;
private int defaultItemY = 10;
private int maxItemCount = 7;
private int initItemX = 20;
private int screenWidth;
private int itemHeight;
private int itemWidth;
private int itemX = getInitItemX();
private int itemY = defaultItemY;
// Auto scroll view task.
private final Runnable mScrollTask = new Runnable() {
@Override
public void run() {
if (canScroll) {
scrollView(SCROLL_OFFSET);
mHandler.postDelayed(this, SCROLL_VELOCITY);// Loop self.
}
}
};
public CycleScrollView(Context context) {
super(context);
onCreate(context);
}
public CycleScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
onCreate(context);
}
public CycleScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
onCreate(context);
}
private void onCreate(Context context) {
mContext = context;
detector = new GestureDetector(this);
mHandler = new Handler();
mScroller = new Scroller(context);
}
public void createIndex() {
if (canScroll) {
mPreIndex = maxItemCount - 1;
mCurrentIndex = 0;
mNextIndex = 1;
mPreView = getChildAt(mPreIndex);
mCurrentView = getChildAt(mCurrentIndex);
mNextView = getChildAt(mNextIndex);
}
}
public void setonItemClickListener(onItemClickListener onItemClickListener) {
monItemClickListener = onItemClickListener;
}
public void setAdapter(CycleScrollAdapter adapter) {
mAdapter = adapter;
}
public void startScroll() {
if (canScroll) {
mHandler.post(mScrollTask);
}
}
public void stopScroll() {
mHandler.removeCallbacks(mScrollTask);
}
public void delayStartScroll() {
if (canScroll) {
mHandler.postDelayed(mScrollTask, TOUCH_DELAYMILLIS);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int count = this.getChildCount();
for (int i = 0; i < count; i++) {
View child = this.getChildAt(i);
child.measure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (reLayout) {// Run one times.
for (int i = 0; i < getChildCount(); i++) {
View child = this.getChildAt(i);
child.setVisibility(View.VISIBLE);
child.layout(itemX, getItemY(), itemX + getItemWidth(),
getItemY() + getItemHeight());
itemX += getItemMargin();
}
reLayout = !reLayout;
}
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if (e1 == null || e2 == null) {
return false;
}
// When deltaX and velocityX not good return false.
if (Math.abs(velocityX) < MAX_VELOCITY_X) {
return false;
}
// Get the delta x.
float deltaX = (e1.getX() - e2.getX());
mHandler.removeCallbacks(mScrollTask);
if (canScroll) {
mHandler.postDelayed(mScrollTask, TOUCH_DELAYMILLIS
+ FLING_DURATION - 1000);
}
mFlingX = (int) deltaX;
// Start scroll with fling x.
mScroller.startScroll(0, 0, mFlingX, 0, FLING_DURATION);
return false;
}
@Override
public void computeScroll() {
if (canScroll && mScroller.computeScrollOffset()) {
int deltaX = mFlingX - mScroller.getCurrX();
scrollView(-deltaX / 10);
postInvalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Get event x,y at parent view.
final float x = ev.getX();
final int rawX = (int) ev.getRawX();
final int rawY = (int) ev.getRawY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// Reset isMoveAction.
isMoveAction = false;
// Get motionX.
mLastMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
// When action move set isMoveAction true.
isMoveAction = true;
// only support one pointer.
if (ev.getPointerCount() == 1) {
// Compute delta X.
int deltaX = 0;
deltaX = (int) (x - mLastMotionX);
mLastMotionX = x;
// When canScroll is true, scrollView width deltaX.
if (canScroll) {
scrollView(deltaX);
}
}
break;
case MotionEvent.ACTION_UP:
if (!isMoveAction) {
View view = getClickItem(rawX, rawY);
if (view != null) {
mOnItemClickListener.onItemClick(Integer.valueOf(view
.getTag().toString()));
}
}
break;
}
return this.detector.onTouchEvent(ev);
}
private View getClickItem(final int rawX, final int rawY) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
// Get item view rect.
Rect rect = new Rect();
child.getGlobalVisibleRect(rect);
// If click point on the item view, invoke the click event.
if (rect.contains(rawX, rawY)) {
return child;
}
}
return null;
}
private void scrollView(int deltaX) {
// Move child view by deltaX.
moveChildView(deltaX);
// After move change index.
if (deltaX < 0) {// move left
// If current at right switch current view to left.
switchCurrentViewToLeft();
// change previous current next index.
moveTonext();
} else {// move right
// If current at left switch current view to right.
switchCurrentViewToRight();
// change previous current next index.
moveToPre();
}
invalidate();
}
private void moveChildView(int deltaX) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.layout(child.getLeft() + deltaX, child.getTop(),
child.getRight() + deltaX, child.getBottom());
}
}
private void switchCurrentViewToLeft() {
if (!mCurrentViewAtLeft) {
mPreIndex = mCurrentIndex;
mCurrentIndex = mNextIndex;
mNextIndex++;
if (mNextIndex > maxItemCount - 1) {
mNextIndex = 0;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
mCurrentViewAtLeft = !mCurrentViewAtLeft;
}
}
private void switchCurrentViewToRight() {
if (mCurrentViewAtLeft) {
mNextIndex = mCurrentIndex;
mCurrentIndex = mPreIndex;
mPreIndex--;
if (mPreIndex < 0) {
mPreIndex = maxItemCount - 1;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
mCurrentViewAtLeft = !mCurrentViewAtLeft;
}
}
private void moveTonext() {
if (mCurrentView.getRight() < 0) {
mCurrentView.layout(mPreView.getLeft() + getItemMargin(),
getItemY(), mPreView.getLeft() + getItemMargin()
+ getItemWidth(), getItemY() + getItemHeight());
if (mCurrentView.getTag() != null) {
int listIndex = (Integer) mCurrentView.getTag();
int index = (listIndex + maxItemCount) % mAdapter.getCount();
mAdapter.bindView(mCurrentView, mAdapter.get(index));
mCurrentView.setTag(index);
}
mPreIndex = mCurrentIndex;
mCurrentIndex = mNextIndex;
mNextIndex++;
if (mNextIndex > maxItemCount - 1) {
mNextIndex = 0;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
moveTonext();
}
}
private void moveToPre() {
if (mCurrentView.getLeft() > getScreenWidth()) {
mCurrentView.layout(mNextView.getLeft() - getItemMargin(),
getItemY(), mNextView.getLeft() - getItemMargin()
+ getItemWidth(), getItemY() + getItemHeight());
if (mCurrentView.getTag() != null) {
int listIndex = (Integer) mCurrentView.getTag();
int index = (listIndex - maxItemCount + mAdapter.getCount())
% mAdapter.getCount();
mAdapter.bindView(mCurrentView, mAdapter.get(index));
mCurrentView.setTag(index);
}
mNextIndex = mCurrentIndex;
mCurrentIndex = mPreIndex;
mPreIndex--;
if (mPreIndex < 0) {
mPreIndex = maxItemCount - 1;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
moveToPre();
}
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
public int getMaxItemCount() {
return maxItemCount;
}
public void setMaxItemCount(int maxItemCount) {
this.maxItemCount = maxItemCount;
}
public void setReLayout(boolean reLayout) {
this.reLayout = reLayout;
}
public void setCanScroll(boolean canScroll) {
this.canScroll = canScroll;
}
public int getItemX() {
return itemX;
}
public void setItemX(int itemX) {
this.itemX = itemX;
}
public int getItemY() {
return itemY;
}
public void setItemY(int itemY) {
this.itemY = itemY;
}
public int getItemWidth() {
return itemWidth;
}
public void setItemWidth(int itemWidth) {
this.itemWidth = itemWidth;
}
public int getItemHeight() {
return itemHeight;
}
public void setItemHeight(int itemHeight) {
this.itemHeight = itemHeight;
}
public int getItemMargin() {
return (screenWidth - itemWidth * (maxItemCount - 1) - initItemX * 2)/(maxItemCount - 2) + itemWidth;
}
public int getScreenWidth() {
return screenWidth;
}
public void setScreenWidth(int screenWidth) {
this.screenWidth = screenWidth;
}
public int getInitItemX() {
return initItemX;
}
public void setInitItemX(int initItemX) {
this.initItemX = initItemX;
}
interface onItemClickListener {
public boolean onItemClick(int position);
}
}
CycleScrollAdapter.java
package com.example.test; import java.util.List; import android.app.Activity; import android.content.Context; import android.util.DisplayMetrics; import android.view.View; public abstract class CycleScrollAdapter{ private List list; private CycleScrollView mCycleScrollView; Context mContext; public CycleScrollAdapter(List list, CycleScrollView cycleScrollView, Context context) { this.list = list; mContext = context; mCycleScrollView = cycleScrollView; mCycleScrollView.setAdapter(this); GetScreenWidthPixels(); initView(list); } private void GetScreenWidthPixels() { DisplayMetrics dm = new DisplayMetrics(); Activity a = (Activity) mContext; a.getWindowManager().getDefaultDisplay().getMetrics(dm); mCycleScrollView.setScreenWidth(dm.widthPixels); } protected void initView(List list) { if (list == null || list.size() == 0) { return; } // Clear all view from ViewGroup at first. mCycleScrollView.removeAllViewsInLayout(); // Loop list. for (int i = 0; i < list.size(); i++) { if (i == mCycleScrollView.getMaxItemCount()) { break; } if (i == list.size() - 1 || i == mCycleScrollView.getMaxItemCount() - 1) { mCycleScrollView.setItemX(mCycleScrollView.getInitItemX()); mCycleScrollView.setReLayout(true); } add(list.get(i), i); } if (list.size() >= mCycleScrollView.getMaxItemCount()) { mCycleScrollView.setCanScroll(true); } else { mCycleScrollView.setCanScroll(false); } mCycleScrollView.createIndex(); } public int getCount() { return list.size(); } public T get(int index) { return list.get(index); } public void addItem(T t) { list.add(t); initView(list); } public void removeItem(T t) { list.remove(t); initView(list); } private void add(T t, int index) { View view = getView(t); ComputeItemSize(view); mCycleScrollView.addView(view); view.setTag(index); } private void ComputeItemSize(View view) { if (mCycleScrollView.getItemWidth() == 0 || mCycleScrollView.getItemHeight() == 0) { int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); view.measure(w, h); int height = view.getMeasuredHeight(); int width = view.getMeasuredWidth(); mCycleScrollView.setItemHeight(height); mCycleScrollView.setItemWidth(width); } } public abstract View getView(T t); public abstract void bindView(View child, T t); }
以上两个是核心类,下面是测试代码。
实现CycleScrollAdapter
AppCycleScrollAdapter.java绑定视图和应用数据
package com.example.test; import java.util.List; import android.content.Context; import android.content.pm.PackageInfo; import android.view.View; import android.widget.ImageView; import android.widget.TextView; public class AppCycleScrollAdapter extends CycleScrollAdapter{ public AppCycleScrollAdapter(List list, CycleScrollView cycleScrollView, Context context) { super(list, cycleScrollView, context); } @Override protected void initView(List list) { super.initView(list); } @Override public void bindView(View child, PackageInfo pi) { ImageView image = (ImageView) child.findViewById(R.id.item_image); TextView text = (TextView) child.findViewById(R.id.item_text); image.setImageDrawable(pi.applicationInfo.loadIcon(mContext .getPackageManager())); text.setText(pi.applicationInfo.loadLabel(mContext.getPackageManager())); } @Override public View getView(PackageInfo pi) { View view = View.inflate(mContext, R.layout.view_item, null); // inflate APP icon view ImageView image = (ImageView) view.findViewById(R.id.item_image); // inflate APP name view TextView text = (TextView) view.findViewById(R.id.item_text); image.setImageDrawable(pi.applicationInfo.loadIcon(mContext .getPackageManager())); text.setText(pi.applicationInfo.loadLabel(mContext.getPackageManager())); return view; } }
入口Activity
package com.example.test;
import java.util.List;
import android.app.Activity;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.view.Menu;
public class MainActivity extends Activity{
private CycleScrollView mCycleScrollView;
private AppCycleScrollAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCycleScrollView = ((CycleScrollView) this.findViewById(R.id.cycle_scroll_view));
List list = this.getPackageManager()
.getInstalledPackages(0);
mAdapter = new AppCycleScrollAdapter(list, mCycleScrollView, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
布局文件
[java] view plain copy
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



