本文实例为大家分享了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;   /**   * Scroll velocity.   */  public static final long SCROLL_VELOCITY = 50;   /**   * Scroll offset.   */  public static final int SCROLL_OFFSET = -1;   /**   * Touch delay.   */  public static final long TOUCH_DELAYMILLIS = 2000;   /**   * Fling duration.   */  public static final int FLING_DURATION = 2000;   /**   * Filing max velocity x.   */  public static final int MAX_VELOCITY_X = 1000;   private GestureDetector detector;  private Handler mHandler;  private Scroller mScroller;   /**   * Callback interface adapter and OnItemClick.   */  private CycleScrollAdapter mAdapter;  private OnItemClickListener mOnItemClickListener;   /**   * Scroll index   */  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;   /**   * The screen width.   */  private int screenWidth;   /**   * Item view height.   */  private int itemHeight;   /**   * Item view width.   */  private int itemWidth;   /**   * Item view layout x.   */  private int itemX = getInitItemX();   /**   * Item view layout y.   */  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);  }   /**   * Create scroll index.   */  public void createIndex() {   if (canScroll) {    mPreIndex = maxItemCount - 1;    mCurrentIndex = 0;    mNextIndex = 1;    mPreView = getChildAt(mPreIndex);    mCurrentView = getChildAt(mCurrentIndex);    mNextView = getChildAt(mNextIndex);   }  }   /**   * Set item click callback.   *   * @param onItemClickListener   *   The callback   */  public void setOnItemClickListener(OnItemClickListener onItemClickListener) {   mOnItemClickListener = onItemClickListener;  }   /**   * Set itemAdapter for addItem and bindItem.   *   * @param itemAdapter   */  public void setAdapter(CycleScrollAdapter adapter) {   mAdapter = adapter;  }   /**   * Start auto scroll.   */  public void startScroll() {   if (canScroll) {    mHandler.post(mScrollTask);   }  }   /**   * Stop auto scroll and filing scroll task.   */  public void stopScroll() {   mHandler.removeCallbacks(mScrollTask);  }   /**   * Delay start auto scroll task.   */  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) {   /**    * On layout set the child view layout by x y width and height.    */   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;   }  }   /**   * When fling view run the fling task scroll view.   */  @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());    /**    * If can fling stop other scroll task at first , delay the task after    * fling.    */   mHandler.removeCallbacks(mScrollTask);   if (canScroll) {    mHandler.postDelayed(mScrollTask, TOUCH_DELAYMILLIS      + FLING_DURATION - 1000);   }    /**    * The flingX is fling distance.    */   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()) {    /**     * The Scroller.getCurrX() approach mFlingX , the deltaX more and     * more small.     */    int deltaX = mFlingX - mScroller.getCurrX();    scrollView(-deltaX / 10);    postInvalidate();   }  }   /**   * When touch event is move scroll child view.   */  @Override  public boolean onTouchEvent(MotionEvent ev) {    // Get event x,y at parent view.   final float x = ev.getX();    /**    * Get event x,y at screen.    */   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 not move find click item and invoke click event.     */    if (!isMoveAction) {     View view = getClickItem(rawX, rawY);     if (view != null) {      mOnItemClickListener.onItemClick(Integer.valueOf(view        .getTag().toString()));     }    }    break;   }   return this.detector.onTouchEvent(ev);  }   /**   * Get click item view by rawX and rawY.   * @param rawX the x at screen.   * @param rawY the y at screen.   * @return the click item view.   */  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;  }   /**   * Scroll view by delta x.   *   * @param deltaX   *   The scroll distance.   */  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();  }   /**   * Move view by delta x.   *   * @param deltaX   *   The move distance.   */  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());   }  }   /**   * Current event is move to left, if current view at right switch current   * view to left.   */  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;   }  }   /**   * Current event is move to right, if current view at left switch current   * view to right.   */  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;   }  }   /**   * Current event is move to left,if current view move out of screen move the   * current view to right and reBind the item change index.   */  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();   }  }   /**   * Current event is move to right,if current view move out of screen move   * the current view to left and reBind the item change index.   */  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;  }   /**   * The interface for item click callback.   */  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;   /**   * Initial CycleScrollAdapter bind list to view.   *   * @param list   *   The list data.   * @param cycleScrollView   *   The CycleScrollView.   * @param context   *   The Context.   */  public CycleScrollAdapter(List list, CycleScrollView cycleScrollView,    Context context) {   this.list = list;   mContext = context;   mCycleScrollView = cycleScrollView;   mCycleScrollView.setAdapter(this);   GetScreenWidthPixels();   initView(list);  }   /**   * Get screen width pixels.   */  private void GetScreenWidthPixels() {   DisplayMetrics dm = new DisplayMetrics();   Activity a = (Activity) mContext;   a.getWindowManager().getDefaultDisplay().getMetrics(dm);   mCycleScrollView.setScreenWidth(dm.widthPixels);  }   /**   * Bind list to view.   *   * @param list   *   The list data.   */  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 list size more than MaxItemCount break the loop, only create     * view count is MaxItemCount.     */    if (i == mCycleScrollView.getMaxItemCount()) {     break;    }     /**     * If list size less than MaxItemCount at the last loop reLayout     * otherwise at the MaxItemCount index reLayout.     */    if (i == list.size() - 1      || i == mCycleScrollView.getMaxItemCount() - 1) {     mCycleScrollView.setItemX(mCycleScrollView.getInitItemX());     mCycleScrollView.setReLayout(true);    }    add(list.get(i), i);   }    /**    * If list count more than MaxItemCount the view can scroll otherwise    * can not scroll.    */   if (list.size() >= mCycleScrollView.getMaxItemCount()) {    mCycleScrollView.setCanScroll(true);   } else {    mCycleScrollView.setCanScroll(false);   }    /**    * If list count more than MaxItemCount reBuild index.    */   mCycleScrollView.createIndex();  }   /**   * Get list size.   *   * @return The list size.   */  public int getCount() {   return list.size();  }   /**   * Returns the element at the specified location in this   *   * @param index   *   the index of the element to return.   * @return the element at the specified location.   */  public T get(int index) {   return list.get(index);  }   /**   * Adds the specified object at the end of this and refresh view.   *   * @param t   *   the object to add.   */  public void addItem(T t) {   list.add(t);   initView(list);  }   /**   * Removes the first occurrence of the specified object from this and   * refresh view.   *   * @param t   *   the object to remove.   */  public void removeItem(T t) {   list.remove(t);   initView(list);  }   /**   * Add the specified view to the index.   *   * @param t   *   The data to add.   * @param index   *   the index.   */  private void add(T t, int index) {   View view = getView(t);   ComputeItemSize(view);   mCycleScrollView.addView(view);   view.setTag(index);  }   /**   * If item size is null compute item size.   *   * @param view   *   the item view.   */  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);   }  }   /**   * Get item view.   *   * @param t   *   the data need bind to view.   * @return the view.   */  public abstract View getView(T t);   /**   * Bind the item to view.   *   * @param child   *   the item view need bind.   * @param t   *   the item.   */  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));    /**    * Get APP list and sort by update time.    */   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;  }  } 

布局文件

<?xml version="1.0" encoding="utf-8"?>          [java] view plain copy           

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多相关文章

  1. android 分享到 代码
  2. Android中NFC功能流程图解析及代码演示『轉』
  3. android 关于 发送post请求的代码总结(包含加上参数)
  4. Android Audio代码分析12 - stream type续
  5. android代码常识
  6. 登录+注册界面的实现(代码)

随机推荐

  1. Android之动画PopupWindow
  2. android View 转Bitmap
  3. Android(安卓)TileMode效果 水波纹效果
  4. android 多点触摸 实现图片缩放 Image Zo
  5. Android的Animation
  6. Android(安卓)IPC 通讯机制源码分析 二
  7. android ndk开发,fatal错误记录
  8. 在Android中创建一个下拉菜单
  9. App内嵌H5页面联调接口
  10. android 设置EditText可输入和不可输入状