利用ViewPager和CirclePageIndicator实现新闻循环滚动

来源:互联网 发布:mac能用几年 编辑:程序博客网 时间:2024/06/05 01:18

Viewpager实现了左右循环滚动,但是无法实现类似网易新闻的循环滚动效果。所以,就自己简单写了一个。




原理:

1.在ViewPager的第一页,插入最后一页的内容。在最后一页,插入原本第一页的内容。

如:原本内容页为A、B、C,则添加后页签内容为 C、A、B、C、A。

2.当从当前的第1页,右滑进入第0页后,迅速将页面切为倒数第二页。

   当从当前的倒数第二页,左滑进入最后一页后,迅速将页面切为倒数第1页。

如:从第一个A,切到C,则页面迅速切换到最后一个C。


具体实现:

1.先看ViewPagerAdapter的3个方法:

  getCount() :指示页签的个数

    此处我们在原来的基础上+2


  destroyItem(View container, int position, Object object):当页签变化时,销毁指定位置的界面

   这里我们选择只销毁中间的界面


  instantiateItem(View container, int position): 当页签变化时,加载指定位置的界面

  此处做逻辑上的处理,当position为0时,加载最后一页。posiiton为最大时,加载第一页


public class PhotoNewsViewPagerAdapter extends PagerAdapter {private ArrayList<View> views = new ArrayList<View>();private List<Article> mData = new ArrayList<Article>();private Context mContext;public PhotoNewsViewPagerAdapter() {// TODO Auto-generated constructor stub}public void setData(Context context,List<Article> data) {mContext = context;mData.clear();mData.addAll(data);LayoutInflater inflater = LayoutInflater.from(context);views.clear();for(Article article:mData){View view = inflater.inflate(R.layout.activity_news_viewpager_item, null);views.add(view);ImageView image = (ImageView) view.findViewById(R.id.iv_photo);image.setOnClickListener(new OnImageClickListener(article));showPhoto(image, article);TextView title = (TextView) view.findViewById(R.id.tv_title);title.setText(article.getTitle());}}public List<Article> getData() {return mData;}@Overridepublic int getCount() {return views.size()+2;}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic int getItemPosition(Object object) {return super.getItemPosition(object);}@Overridepublic void destroyItem(View container, int position, Object object) {if(position>1&&position<views.size()){((ViewPager) container).removeView(views.get(getPosition(position)));}}@Overridepublic Object instantiateItem(View container, int position) {try {((ViewPager) container).addView(views.get(getPosition(position)));} catch (Exception e) {// TODO: handle exception}return views.get(getPosition(position));}private int getPosition(int position){int count = views.size();if(position==0){return count-1;}else if(position==count+1){return 0;}else{return position-1;}}/** * 显示图片 * @param view 显示的view * @param newsBean 新闻对象 */private void showPhoto(ImageView view, Article newsBean) {String photoPath = SystemUtil.getPhotoUrl(mContext, newsBean.getPhotoPath());// 如果有图片,则显示//配置图片加载及显示选项(还有一些其他的配置,查阅doc文档吧)DisplayImageOptions options = new DisplayImageOptions.Builder().showStubImage(R.drawable.ic_empty)    //在ImageView加载过程中显示图片    .showImageForEmptyUri(R.drawable.ic_empty)  //image连接地址为空时.showImageOnFail(R.drawable.ic_empty)  //image加载失败.cacheInMemory(true)  //加载图片时会在内存中加载缓存.cacheOnDisc(true)   //加载图片时会在磁盘中加载缓存.displayer(new RoundedBitmapDisplayer(1))  //设置用户加载图片task(这里是圆角图片显示).build();// 图片加载器ImageLoader imageLoader = ImageLoader.getInstance();// 图片加载监听事件ImageLoadingListener animateFirstListener = new SimpleImageLoadingListener();//先在加载前显示默认图片imageLoader.displayImage("", view, options, animateFirstListener);//加载缩略图imageLoader.displayImage(photoPath, view, options, animateFirstListener);}private class OnImageClickListener implements OnClickListener{private Article article;public OnImageClickListener(Article article) {this.article = article;}@Overridepublic void onClick(View v) {}};}



2.给ViewPager加页面切换监听

indicator.setOnPageChangeListener(new OnPageChangeListener() {//当前的索引private int currentIndex = 1;@Overridepublic void onPageSelected(int arg0) {currentIndex = arg0;}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic void onPageScrollStateChanged(int arg0) {//滑动停止后,再切换,效果会好一点if(arg0 == 0){if(currentIndex==0){viewPager.setCurrentItem(photoAdapter.getCount()-2, false);}else if(currentIndex==photoAdapter.getCount()-1){viewPager.setCurrentItem(1, false);}}}});
至此,ViewPager循环切换就做好了,接下来就是底部页签指示标志的修改。


3.由于我们多加了两个页面,导致CirclePageIndicator显示的时候会多两个点,所以要修改其源码。


增加mIsLoopViewPager 属性,兼容循环ViewPager。

修改下面的代码,把第一个和最后一个点,屏蔽掉。

    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        ...        //Draw stroked circles        int startIndex = 0;        int endIndex = count;        if(mIsLoopViewPager){        startIndex = 1;        endIndex = count-1;        }        for (int iLoop = startIndex; iLoop < endIndex; iLoop++) {            float drawLong = longOffset + (iLoop * threeRadius);            if (mOrientation == HORIZONTAL) {                dX = drawLong;                dY = shortOffset;            } else {                dX = shortOffset;                dY = drawLong;            }            // Only paint fill if not completely transparent            if (mPaintPageFill.getAlpha() > 0) {                canvas.drawCircle(dX, dY, pageFillRadius, mPaintPageFill);            }            // Only paint stroke if a stroke width was non-zero            if (pageFillRadius != mRadius) {                canvas.drawCircle(dX, dY, mRadius, mPaintStroke);            }        }        ...    }

    对CirclePageIndicator不清楚的,参考 http://my.oschina.net/u/1403288/blog/208402


    收工。



0 0
原创粉丝点击