首页 > 系统 > Android > 正文

Android简单实现无限滚动自动滚动的ViewPager

2019-12-12 04:12:09
字体:
来源:转载
供稿:网友

经常我们会在应用中看到一个可以自动滚动,并且无限滚动的一个ViewPager,百度谷歌上面也有很多关于这方面的教程,但是感觉都略显麻烦,而且封装的都不是很彻底。所以试着封装一个比较好用的ViewPager

效果如下:

简单的说一下实现思路,要实现无限滚动的话就要在PagerAdapter上面做一些手脚,在PagerAdapter的getCount的函数的返回值设置成Integer.MXA_VALUE就可以实现向右无限滚动,但是要实现向左无限滚动呢?就是一开始的时候setCurrentItem的时候设置一个非常大的值(大到你向左滚动了一万年还是有东西)

@Override     public int getCount() {       return Integer.MAX_VALUE;     } 
mPager.setCurrentItem(10000 * mDatas.size());//一开始设置成这样的话就可以向左无限滚动了 

然后另外一个就是底部的游标了:

底部的游标是用一个自定义视图:无非就是画一个背景,然后在画一个高亮的游标

/**   * 指示游标   */   private class TipView extends View {     private int mPadding;     private int mCount;     private int mCurPos;     private Paint mNorPaint;//未被选中的颜色     private Paint mSelPaint;//被选中的颜色 白色     private int mHeight;     public TipView(Context context, int count) {       super(context);       mNorPaint = new Paint();       mNorPaint.setAntiAlias(true);       int selHeight = ShowUtils.dip2px(2);       int norHeight = ShowUtils.dip2px(1);       mHeight = ShowUtils.dip2px(2);       mNorPaint.setStrokeWidth(norHeight);       mNorPaint.setColor(Color.argb(80, 255, 255, 255));       mSelPaint = new Paint();       mSelPaint.setAntiAlias(true);       mSelPaint.setStrokeWidth(selHeight);       mSelPaint.setColor(Color.WHITE);       mCount = count;       mPadding = ShowUtils.dip2px(0);     }     @Override     protected void onDraw(Canvas canvas) {       super.onDraw(canvas);       int ow = (getWidth()-2 * mPadding)/ mCount;       int y = getHeight() / 2;       canvas.drawLine(mPadding, y, mCurPos * ow + mPadding, y, mNorPaint);       canvas.drawLine(mCurPos * ow + mPadding, y, (mCurPos + 1) * ow + mPadding, y, mSelPaint);       canvas.drawLine((mCurPos + 1) * ow + mPadding, y, getWidth() - mPadding, y, mNorPaint);     }     @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {       ViewGroup.LayoutParams vp = getLayoutParams();       vp.width = ViewGroup.LayoutParams.MATCH_PARENT;       vp.height = mHeight;       super.onMeasure(widthMeasureSpec, heightMeasureSpec);     }     public void setCurPostion(int pos) {       mCurPos = pos;       invalidate();     }     public void setCount(int count) {       mCount = count;     }   } 

R.layout.layout_recommend_item的布局:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="match_parent"   android:layout_height="match_parent">   <ImageView     android:id="@+id/iv_pic"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:contentDescription="@null"     android:scaleType="fitXY"/>   <LinearLayout     android:layout_width="match_parent"     android:layout_height="48dp"     android:orientation="vertical"     android:layout_alignParentBottom="true"     android:background="@drawable/recommend"     android:gravity="center">     <TextView       android:id="@+id/tv_desc"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@color/white"       android:textSize="@dimen/text_normal"       android:maxLines="1"       android:ellipsize="end"       android:shadowColor="#ff333333"       android:shadowDx="2"       android:shadowDy="2"       android:paddingRight="8dp"       android:paddingLeft="8dp"       android:shadowRadius="1" />   </LinearLayout> </RelativeLayout> 

还有一个是实现自动滚动,自动滚动的话就是监听OnPagerChangeListener里面的函数,在ViewPager状态改变的时候利用Handler发送一个切换界面的消息:

@Override     public void onPageScrollStateChanged(int i) {       curState = i;       if(i == ViewPager.SCROLL_STATE_DRAGGING){  //viewpager正在被拖动的时候         stopAnimation();       }else { //没有可执行消息时候添加消息 实现自动滚动         if(!(sHandler.hasMessages(START_SCROLL)&&sHandler.hasMessages(SCROLL_NEXT))){           startAnimation();         }       }     }     @Override     public void onPageSelected(final int i) {  //页面跳转后得到调用       sHandler.removeMessages(SCROLL_NEXT);       sHandler.removeMessages(START_SCROLL);       if(curState == ViewPager.SCROLL_STATE_DRAGGING){         return;       }       Message msg = sHandler.obtainMessage(SCROLL_NEXT);       msg.arg1 = i + 1;       msg.obj = mPager;       sHandler.sendMessageDelayed(msg, SHOW_TIME);       mTipView.setCurPostion(i % mDatas.size());     } 

整体的代码:

import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.papau.show.R; import com.papau.show.entity.HeadViewEntity; import com.papau.show.utils.ShowUtils; import java.util.ArrayList; import java.util.List; public class RecommendView extends RelativeLayout implements IRecommend {   private static final int START_SCROLL = 1;   private static final int SCROLL_NEXT = 2;   private static final int SHOW_TIME = 5000;   private List<HeadViewEntity> mDatas = new ArrayList<>();   private ViewPager mPager;   private Context mContext;   private int mWidth, mHeight;   private ImageLoader mLoader;   private DisplayImageOptions mOptions;   private int mTitleHeight;   private TipView mTipView;   private static Handler sHandler = new Handler() {     @Override     public void handleMessage(Message msg) {       int w = msg.what;       ViewPager pager = (ViewPager) msg.obj;       switch (w) {         case START_SCROLL:           pager.setCurrentItem(msg.arg1, true);           break;         case SCROLL_NEXT:           pager.setCurrentItem(msg.arg1, true);           break;       }     }   };   public RecommendView(Context context) {     super(context);   }   public RecommendView(Context context, int w, int h) {     super(context);     mContext = context;     mWidth = w;     mHeight = h;     initView(); //    mPager.setAdapter(new RecommendAdapter());     mPager.setOnPageChangeListener(new MOnPagerChangeListener());     mLoader = ImageLoaderManager.getImageLoader(mContext);     mOptions = ImageLoaderManager.getCacheOnDiskOptions(mContext);     init(); //    DisplayMetrics dm = mContext.getResources().getDisplayMetrics();     mTitleHeight = ShowUtils.dip2px(48);//设置游标高度   }   @Override   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {     ViewGroup.LayoutParams vp = getLayoutParams();     if (vp != null) {  //设置视图的宽高       vp.width = mWidth;       vp.height = mHeight;     }     super.onMeasure(widthMeasureSpec, heightMeasureSpec);   }   private void initView() {     mPager = new ViewPager(mContext);     RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);     addView(mPager, rp);   }   /**    * 初始化指示游标    */   private void initTipView() {     if (mTipView == null) {       RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(10, 10);       rp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);//显示在父控件的底部       rp.bottomMargin = mTitleHeight;//游标的高度       mTipView = new TipView(mContext, mDatas.size());       addView(mTipView, rp);     } else {       mTipView.setCount(mDatas.size());     }   }   @Override   public void upDate() {     getData();   }   @Override   public void init() {     getData();   }   @Override   public void startAnimation() {     if (mDatas.size() == 0) {       return;     }     Message msg = sHandler.obtainMessage(START_SCROLL);     msg.obj = mPager;     msg.arg1 = (mPager.getCurrentItem() + 1);     sHandler.sendMessageDelayed(msg, SHOW_TIME);   }   @Override   public void stopAnimation() {     sHandler.removeMessages(START_SCROLL);     sHandler.removeMessages(SCROLL_NEXT);   }   /**    * 获取viewpager要显示的数据    */   private void getData() {     String[] imageData = new String[]{"http://f.hiphotos.baidu.com/image/h%3D360/sign=e105b9f1d61b0ef473e89e58edc651a1/b151f8198618367a9f738e022a738bd4b21ce573.jpg",         "http://c.hiphotos.baidu.com/image/h%3D360/sign=b8cea9e92b738bd4db21b437918b876c/f7246b600c3387448982f948540fd9f9d72aa0bb.jpg",         "http://a.hiphotos.baidu.com/image/h%3D360/sign=3da95d01e7dde711f8d245f097eecef4/71cf3bc79f3df8dc39cb6295cf11728b461028c4.jpg",         "http://d.hiphotos.baidu.com/image/h%3D360/sign=410c3c96a60f4bfb93d09852334f788f/10dfa9ec8a136327a1de913a938fa0ec08fac78c.jpg",         "http://e.hiphotos.baidu.com/image/h%3D360/sign=f6600b1613dfa9ece22e501152d1f754/342ac65c10385343ff41ee2b9113b07eca808829.jpg"};     for (int i = 0; i < 5; i++) {       HeadViewEntity info = new HeadViewEntity();       info.setImageUrl(imageData[i]);       info.setTitle("我不做大哥好多年"+i);       info.setUrl("www.baidu.com");       mDatas.add(info);     }     sHandler.postDelayed(new Runnable() {       @Override       public void run() {         stopAnimation();         initTipView();         mPager.setAdapter(new RecommendAdapter());         mPager.setCurrentItem(10000 * mDatas.size());//一开始设置成这样的话就可以向左无限滚动了       }     },2000);   }   /**    * viewpager子项内容    */   private class RecommendAdapter extends PagerAdapter {     /**      * 填充子项视图的内容      * @param container 父控件 viewpager      * @param position 子项的位置      * @return 返回子项视图      */     @Override     public Object instantiateItem(ViewGroup container, int position) {       int curPos = position % mDatas.size();       View view = View.inflate(mContext, R.layout.layout_recommend_item, null);       ViewGroup.LayoutParams vp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);       ImageView iv = (ImageView) view.findViewById(R.id.iv_pic);       TextView tv = (TextView) view.findViewById(R.id.tv_desc);       tv.setText(mDatas.get(curPos).getTitle());       mLoader.displayImage(mDatas.get(curPos).getImageUrl(), iv, mOptions);       container.addView(view, vp);       view.setTag(curPos);       view.setOnClickListener(new OnClickListener() {         @Override         public void onClick(View v) {         }       });       return view;     }     @Override     public void destroyItem(ViewGroup container, int position, Object object) {       container.removeView((View) object);     }     @Override     public int getCount() {       return Integer.MAX_VALUE;     }     @Override     public boolean isViewFromObject(View view, Object o) {       return view == o;     }   }   private class MOnPagerChangeListener implements ViewPager.OnPageChangeListener {     private int curState;     @Override     public void onPageScrolled(int i, float v, int i1) {     }     @Override     public void onPageScrollStateChanged(int i) {       curState = i;       if(i == ViewPager.SCROLL_STATE_DRAGGING){  //viewpager正在被拖动的时候         stopAnimation();       }else { //没有可执行消息时候添加消息 实现自动滚动         if(!(sHandler.hasMessages(START_SCROLL)&&sHandler.hasMessages(SCROLL_NEXT))){           startAnimation();         }       }     }     @Override     public void onPageSelected(final int i) {  //页面跳转后得到调用       sHandler.removeMessages(SCROLL_NEXT);       sHandler.removeMessages(START_SCROLL);       if(curState == ViewPager.SCROLL_STATE_DRAGGING){         return;       }       Message msg = sHandler.obtainMessage(SCROLL_NEXT);       msg.arg1 = i + 1;       msg.obj = mPager;       sHandler.sendMessageDelayed(msg, SHOW_TIME);       mTipView.setCurPostion(i % mDatas.size());     }   }   /**    * 指示游标    */   private class TipView extends View {     private int mPadding;     private int mCount;     private int mCurPos;     private Paint mNorPaint;//未被选中的颜色     private Paint mSelPaint;//被选中的颜色 白色     private int mHeight;     public TipView(Context context, int count) {       super(context);       mNorPaint = new Paint();       mNorPaint.setAntiAlias(true);       int selHeight = ShowUtils.dip2px(2);       int norHeight = ShowUtils.dip2px(1);       mHeight = ShowUtils.dip2px(2);       mNorPaint.setStrokeWidth(norHeight);       mNorPaint.setColor(Color.argb(80, 255, 255, 255));       mSelPaint = new Paint();       mSelPaint.setAntiAlias(true);       mSelPaint.setStrokeWidth(selHeight);       mSelPaint.setColor(Color.WHITE);       mCount = count;       mPadding = ShowUtils.dip2px(0);     }     @Override     protected void onDraw(Canvas canvas) {       super.onDraw(canvas);       int ow = (getWidth()-2 * mPadding)/ mCount;       int y = getHeight() / 2;       canvas.drawLine(mPadding, y, mCurPos * ow + mPadding, y, mNorPaint);       canvas.drawLine(mCurPos * ow + mPadding, y, (mCurPos + 1) * ow + mPadding, y, mSelPaint);       canvas.drawLine((mCurPos + 1) * ow + mPadding, y, getWidth() - mPadding, y, mNorPaint);     }     @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {       ViewGroup.LayoutParams vp = getLayoutParams();       vp.width = ViewGroup.LayoutParams.MATCH_PARENT;       vp.height = mHeight;       super.onMeasure(widthMeasureSpec, heightMeasureSpec);     }     public void setCurPostion(int pos) {       mCurPos = pos;       invalidate();     }     public void setCount(int count) {       mCount = count;     }   } } 

然后提供了一个接口调用:

/**  * RecommendView接口  */ public interface IRecommend {   void upDate();   void init();   void startAnimation();   void stopAnimation(); }

图片的加载用到了ImageLoad库:

import android.content.Context; import android.graphics.Bitmap; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.papau.show.constant.Constants; import java.io.File; public class ImageLoaderManager {   /**    * 不带硬盘缓存的options    *    * @param context    * @return    */   public static synchronized DisplayImageOptions getCacheOnMemoryOptions(Context context) {     DisplayImageOptions options = new DisplayImageOptions.Builder()         .cacheInMemory(true)         .cacheOnDisk(false)         .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)         .bitmapConfig(Bitmap.Config.ARGB_8888) //        .showImageOnLoading( //            context.getResources().getDrawable( //                R.drawable.loading_wait)) //        .showImageOnFail( //            context.getResources().getDrawable( //                R.drawable.loading_wait))         .build();     return options;   }   public static synchronized DisplayImageOptions getCircleOptions(Context context) {     DisplayImageOptions options = new DisplayImageOptions.Builder()         .cacheInMemory(true)         .cacheOnDisk(false)         .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)         .bitmapConfig(Bitmap.Config.ARGB_8888) //        .showImageOnLoading( //            context.getResources().getDrawable( //                R.drawable.ic_user_head_hint)) //        .showImageOnFail( //            context.getResources().getDrawable( //                R.drawable.ic_user_head_hint))         .build();     return options;   }   /**    * 获取在硬盘中缓存options    *    * @param context    * @return options    */   public static synchronized DisplayImageOptions getCacheOnDiskOptions(       Context context) {     DisplayImageOptions options = new DisplayImageOptions.Builder()         .cacheInMemory(true)         .cacheOnDisk(true)         .imageScaleType(ImageScaleType.EXACTLY)         .bitmapConfig(Bitmap.Config.ARGB_8888) //        .showImageOnLoading( //            context.getResources().getDrawable( //                R.drawable.loading_wait)) //        .showImageOnFail( //            context.getResources().getDrawable( //                R.drawable.loading_wait))         .build();     return options;   }   /**    * 获取imageLoader 单例    *    * @param context    * @return    */   public static synchronized ImageLoader getImageLoader(Context context) {     ImageLoader imageLoader = ImageLoader.getInstance();     File cacheDir = new File(Constants.sPicCacheLocalPath);     ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(         context).diskCache(new UnlimitedDiskCache(cacheDir))         .threadPoolSize(3)         .diskCacheExtraOptions(480, 320, null)         .build();     imageLoader.init(config);     return imageLoader;   } } 

使用方法

DisplayMetrics dm = getActivity().getResources().getDisplayMetrics();     RecommendView rv = new RecommendView(getActivity(),dm.widthPixels ,(dm.widthPixels)/2);     headViewPager.addView(rv); 

以上所述是小编给大家介绍的Android简单实现无限滚动自动滚动的ViewPager,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表