博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 使用RecyclerView实现轮播图
阅读量:6894 次
发布时间:2019-06-27

本文共 11074 字,大约阅读时间需要 36 分钟。

hot3.png

一、需求

之前一篇博客使用ViewPager实现轮播图《》,但是ViewPager有个天生的缺陷是View无法重用,此外ViewPager的滑动过程会频繁requestLayout,尽管可以通过addViewInLayout和removeViewInLayout配合PagerAdapter 的startUpdate和finishUpdate可以减少重绘,但在ListView和RecyclerView中仍然达不到最好的效果。因此,使用一种新的方式十分必要。

 

二、代码实现

RecyclerPagerView 

public class RecyclerPagerView extends RecyclerView implements Handler.Callback {    private static final long TASK_TIMEOUT = 3000;    public OnPageChangeListener onPageChangeListener;    private final Handler mRecyclerHandler;    private final int MSG_PLAY_NEXT  = 112233;    private volatile boolean isPlaying = false;    private boolean lastIsPlayState = false;    private int realPosition = -1;    public RecyclerPagerView(Context context) {        this(context,null);    }    public RecyclerPagerView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs,0);    }    public RecyclerPagerView(Context context, @Nullable AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        mRecyclerHandler = new Handler(Looper.getMainLooper(),this);    }    public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) {        this.onPageChangeListener = onPageChangeListener;        if(this.onPageChangeListener!=null){            addOnScrollListener(this.onPageChangeListener);            int currentItem = getCurrentItem();            this.onPageChangeListener.onPageSelection(currentItem);        }    }    public int getCurrentItem(){        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();        return linearLayoutManager.findFirstVisibleItemPosition();    }    public void setCurrentItem(int position,boolean isAnimate){        Adapter adapter = getAdapter();        if(adapter==null || adapter.getItemCount()<=position){            return;        }        if(!isAnimate)        {            scrollToPosition(position);        }else {            smoothScrollToPosition(position);        }    }    public void setCurrentItem(int position ){       setCurrentItem(position,true);    }    @Override    public boolean fling(int velocityX, int velocityY) {        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();        int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;        // views on the screen        int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();        View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);        int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();        View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);        // distance we need to scroll        int leftMargin = (screenWidth - lastView.getWidth()) / 2;        int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();        int leftEdge = lastView.getLeft();        int rightEdge = firstView.getRight();        int scrollDistanceLeft = leftEdge - leftMargin;        int scrollDistanceRight = rightMargin - rightEdge;        int targetPosition;        if (Math.abs(velocityX) < 1500) {            // The fling is slow -> stay at the current page if we are less than half through,            // or go to the next page if more than half through            if (leftEdge > screenWidth / 2) {                // go to next page                smoothScrollBy(-scrollDistanceRight, 0);                targetPosition = firstVisibleItemPosition;            } else if (rightEdge < screenWidth / 2) {                // go to next page                smoothScrollBy(scrollDistanceLeft, 0);                targetPosition = firstVisibleItemPosition+1;            } else {                // stay at current page                if (velocityX > 0) {                    smoothScrollBy(-scrollDistanceRight, 0);                } else {                    smoothScrollBy(scrollDistanceLeft, 0);                }                targetPosition = firstVisibleItemPosition;            }        } else {            // The fling is fast -> go to next page            if (velocityX > 0) {                smoothScrollBy(scrollDistanceLeft, 0);                targetPosition = firstVisibleItemPosition+1;            } else {                smoothScrollBy(-scrollDistanceRight, 0);                targetPosition = firstVisibleItemPosition;            }        }        Log.e("RecyclerPagerView","nextPage="+targetPosition);        if(this.onPageChangeListener!=null){            realPosition = targetPosition;            this.onPageChangeListener.onPageSelection(targetPosition);        }        return true;    }    @Override    public void onScrollStateChanged(final  int state) {        super.onScrollStateChanged(state);        if (state == SCROLL_STATE_IDLE) {            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();            int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;            int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();            View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);            int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();            View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);            // distance we need to scroll            int leftMargin = (screenWidth - lastView.getWidth()) / 2;            int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();            int leftEdge = lastView.getLeft();            int rightEdge = firstView.getRight();            int scrollDistanceLeft = leftEdge - leftMargin;            int scrollDistanceRight = rightMargin - rightEdge;            int  targetPosition = -1;            if (leftEdge > screenWidth / 2) {                smoothScrollBy(-scrollDistanceRight, 0);                targetPosition = firstVisibleItemPosition+1;            } else if (rightEdge < screenWidth / 2) {                smoothScrollBy(scrollDistanceLeft, 0);                targetPosition = lastVisibleItemPosition;            }else{                targetPosition = firstVisibleItemPosition;            }            if(this.onPageChangeListener!=null){                realPosition = targetPosition;                this.onPageChangeListener.onPageSelection(targetPosition);            }        }    }    @Override    public boolean handleMessage(Message msg) {        int what = msg.what;        switch (what){            case MSG_PLAY_NEXT:                showNextPage();                break;        }        return false;    }    private void showNextPage() {        if(!isPlaying){            return;        }        if(!canRecyclePlaying()){            isPlaying = false;            return;        }        Adapter adapter = getAdapter();        int currentItem = getCurrentItem();        if(adapter!=null && adapter.getItemCount()>0) {            if (currentItem == NO_POSITION  ) {                setCurrentItem(0);            }else {                setCurrentItem(currentItem+1);            }        }        mRecyclerHandler.sendEmptyMessageDelayed(MSG_PLAY_NEXT,TASK_TIMEOUT);    }    public void startPlay(){        if(isPlaying){            stopPlay();        }        if (!canRecyclePlaying()){            isPlaying = false;            return;        }        isPlaying = true;        mRecyclerHandler.sendEmptyMessageDelayed(MSG_PLAY_NEXT,TASK_TIMEOUT);    }    @Override    public void setAdapter(Adapter adapter) {        super.setAdapter(adapter);        if(canRecyclePlaying()){            if(realPosition==-1){                realPosition = 1000;            }            setCurrentItem(realPosition,false);        }    }    private boolean canRecyclePlaying() {        Adapter adapter = getAdapter();        if(adapter==null || adapter.getItemCount()<1) return false;        return true;    }    private void stopPlay() {        isPlaying = false;        mRecyclerHandler.removeMessages(MSG_PLAY_NEXT);    }    @Override    protected void onAttachedToWindow() {        super.onAttachedToWindow();        if(lastIsPlayState){            startPlay();        }    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        lastIsPlayState = isPlaying;        stopPlay();    }    public static    abstract class OnPageChangeListener extends RecyclerView.OnScrollListener{            public abstract  void onPageSelection(int position);    }}

 

Adapter+Holder 适配器

该类的作用主要用于约束和快速接入

public class QuickViewHolder extends RecyclerView.ViewHolder{    private SparseArray
mViews; private View mConvertView; private QuickViewHolder(View v){ super(v); mConvertView = v; mViews = new SparseArray<>(); } public static QuickViewHolder get(ViewGroup parent, int layoutId){ View convertView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); return new QuickViewHolder(convertView); } public
T getView(int id){ View v = mViews.get(id); if(v == null){ v = mConvertView.findViewById(id); mViews.put(id, v); } return (T)v; }}

 

BannerAdapter实现,该类继承QuickAdapter

public class BannerAdapter extends QuickAdapter
{ public BannerAdapter(List
datas) { super(datas); } @Override public int getLayoutId(int viewType) { return R.layout.item_banner_image; } @Override public void convert(QuickViewHolder holder, String url, int position) { final Resources resources = holder.itemView.getResources(); final int drawableId = resources.getIdentifier(url, "drawable", holder.itemView.getContext().getPackageName()); if(drawableId!=0) { ImageView bannerImage = holder.getView(R.id.banner_image_item); bannerImage.setImageResource(drawableId); } }}

 

三、使用

final RecyclerPagerView rpv  = findViewById(R.id.recycler_pager);        tipTextView                  = findViewById(R.id.tip_text);        LinearLayoutManager lm = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);        rpv.setLayoutManager(lm);        List
imagelist = new ArrayList<>(); imagelist.add("banner_t1"); imagelist.add("banner_t2"); imagelist.add("banner_t3"); imagelist.add("banner_t4"); rpv.setAdapter(new BannerAdapter(imagelist)); rpv.setOnPageChangeListener(new PagerChangeListener(tipTextView,imagelist.size())); rpv.startPlay();

监听器

public static class  PagerChangeListener extends RecyclerPagerView.OnPageChangeListener {        private TextView tipTextView;        private int size;        public PagerChangeListener(TextView tipTextView,int size) {            this.tipTextView = tipTextView;            this.size = size;        }        @Override        public void onPageSelection(int position) {            tipTextView.setText((position%size+1)+"/"+size);        }    }

 

 

转载于:https://my.oschina.net/ososchina/blog/3043596

你可能感兴趣的文章
我的友情链接
查看>>
我的友情链接
查看>>
主机屋使用感受
查看>>
卫星大锅上网链接调试
查看>>
我的友情链接
查看>>
Lync Server 2013企业版部署系列之二:准备DNS
查看>>
实战免费公网证书申请
查看>>
TCP/IP建立连接(三次握手)和关闭连接(四次挥手)
查看>>
Android dex分包方案
查看>>
CAS sso配置
查看>>
【转载】持久层框架 Apache Cayenne 推介
查看>>
我还是个旱鸭子
查看>>
兰蔻 - 2010全新版 柔皙轻透防晒乳
查看>>
我的友情链接
查看>>
python 沙盒环境
查看>>
zabbix发送短信告警脚本
查看>>
js中如何快速获取数组中的最大值最小值
查看>>
易维信(EVTrust)支招五大技巧识别钓鱼网站
查看>>
揭秘腾讯大数据冰山一角
查看>>
php位运算符”|”和逻辑运算符”||”
查看>>