温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何在android中使用水平循环滚动控件

发布时间:2021-06-27 11:25:46 来源:亿速云 阅读:339 作者:Leah 栏目:移动开发

这期内容当中小编将会给大家带来有关如何在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<T> 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<T> 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<T> 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<T> {     private List<T> list;   private CycleScrollView<T> 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<T> list, CycleScrollView<T> 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<T> 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<PackageInfo> {      public AppCycleScrollAdapter(List<PackageInfo> list,     CycleScrollView<PackageInfo> cycleScrollView, Context context) {    super(list, cycleScrollView, context);   }      @Override   protected void initView(List<PackageInfo> 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<PackageInfo> mCycleScrollView;   private AppCycleScrollAdapter mAdapter;      @Override   public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);        mCycleScrollView = ((CycleScrollView<PackageInfo>) this.findViewById(R.id.cycle_scroll_view));      /**     * Get APP list and sort by update time.     */    List<PackageInfo> 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"?>  <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   >     <ImageView    android:id="@+id/item_image"    android:layout_width="60dip"    android:layout_height="60dip"    android:layout_y="5dip"    android:layout_x="10dip"     />     <TextView    android:id="@+id/item_text"    android:layout_width="80dip"    android:layout_height="20dip"    android:layout_y="65dip"    android:layout_x="0dip"    android:gravity="center_horizontal" />    </AbsoluteLayout>  [java] view plain copy <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:tools="http://schemas.android.com/tools"   android:layout_width="match_parent"   android:layout_height="match_parent" >     <TextView    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_centerHorizontal="true"    android:layout_centerVertical="true"    android:text="@string/hello_world"    tools:context=".MainActivity" />       <com.example.test.CycleScrollView    android:id="@+id/cycle_scroll_view"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="#B9000000"    />    </RelativeLayout>

上述就是小编为大家分享的如何在android中使用水平循环滚动控件了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI