日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用RecyclerView打造一个轮播图

發(fā)布時間:2024/4/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用RecyclerView打造一个轮播图 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

通常Android的輪播圖(俗名:Banner)都是用ViewPager實現(xiàn)的,但是我在實際項目運用中碰到了一些小問題,于是決定另尋思路,采用RecyclerView這個更優(yōu)雅更強大的控件來實現(xiàn)輪播的功能,順便復(fù)習下RecyclerView的相關(guān)知識。

實現(xiàn)

一般輪播圖就兩個重要的部分:可以無限左右滑動的圖片流和圖片位置的標示點,可能更簡單的連指示點都省略了。主要的難點還是在前者,因為一個輪播圖要播放的圖片一般也就十來張,不做任何處理直接塞到RecyclerView里面,不僅稍微滑一下就沒了而且開始還不能先往左邊滑,所以我們需要在設(shè)置Adapter的總數(shù)時設(shè)置成一個比較大的數(shù)(可以是Integer.MAX_VALUE),然后在設(shè)置完圖片數(shù)據(jù)后把RecyclerView的當前位置轉(zhuǎn)到中間的一個數(shù)(為了保證從第一張開始播放,必須是圖片總數(shù)的倍數(shù),比如10000*size),這樣item回收復(fù)用的時候,我們只要取當前位置和圖片數(shù)量的余數(shù),得到真正的圖片位置。聽起來有點復(fù)雜,還是直接看下代碼吧:

private class RecyclerAdapter extends RecyclerView.Adapter {List<String> urlList;public void setData(List<String> urlList) {this.urlList = urlList;}@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {return new RecyclerView.ViewHolder(new ImageView(getContext())) { };}@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {if (urlList == null || urlList.isEmpty())return;String url = urlList.get(position % bannerSize);Glide.with(getContext()).load(url).into((ImageView) holder.itemView);}@Overridepublic int getItemCount() {//如果只有一張圖片就不滑動了return bannerSize < 2 ? 1 : Integer.MAX_VALUE;}}復(fù)制代碼

至于自動滑動圖片,就用Handler不斷延遲發(fā)送消息就好了:

private Handler mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {if (msg.what == WHAT_AUTO_PLAY) {mRecyclerView.smoothScrollToPosition(++currentIndex);refreshIndicator();mHandler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, autoPlayDuration);}return false;}});復(fù)制代碼

好了,無限輪播解決了,接下來就是標示點了,既然無限輪播圖都用RecyclerView解決了,那么標示點也用它來解決吧:

private class IndicatorAdapter extends RecyclerView.Adapter {int currentPosition = 0;public void setPosition(int currentPosition) {this.currentPosition = currentPosition;}@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {return new RecyclerView.ViewHolder(new ImageView(getContext())) {};}@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {ImageView bannerPoint = (ImageView) holder.itemView;bannerPoint.setImageDrawable(currentPosition == position ? mSelectedDrawable : mUnselectedDrawable);}@Overridepublic int getItemCount() {return bannerSize;}}復(fù)制代碼

其實Adapter也很簡單,設(shè)置一個當前位置的標識點,然后在圖片改變的時候notifyDataSetChanged()就行了。
好了最后就剩下怎么監(jiān)聽RecyclerView的位置改變了(可沒有像Viewpager的addOnPageChangeListener那么直接的方法),沒辦法直接分析RecyclerView.OnScrollListener中的回調(diào)方法吧:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrolled(RecyclerView recyclerView, int dx, int dy) {//解決連續(xù)滑動時指示器不更新的問題if (bannerSize < 2) return;int firstReal = mLinearLayoutManager.findFirstVisibleItemPosition();View viewFirst = mLinearLayoutManager.findViewByPosition(firstReal);float width = getWidth();if (width != 0 && viewFirst != null) {float right = viewFirst.getRight();float ratio = right / width;if (ratio > 0.8) {if (currentIndex != firstReal) {currentIndex = firstReal;refreshIndicator();}} else if (ratio < 0.2) {if (currentIndex != firstReal + 1) {currentIndex = firstReal + 1;refreshIndicator();}}}}@Overridepublic void onScrollStateChanged(RecyclerView recyclerView, int newState) {//連續(xù)滑動時可能不會回調(diào)int first = mLinearLayoutManager.findFirstVisibleItemPosition();int last = mLinearLayoutManager.findLastVisibleItemPosition();if (currentIndex != first && first == last) {currentIndex = first;refreshIndicator();}}});復(fù)制代碼

看看成果

好了解決了這些東西,再加些自定義View常用的屬性,回調(diào)方法,設(shè)置的接口,輪播圖就做好了,我們來看看效果:

gif.gif

嗯,看著還不錯,可是怎么有點怪?唉,這圖片怎么滑動的這么快,而且還能停在中間,這個不是我們想要的`標準`輪播圖。要解決這個問題就要用到RecyclerView的另一個功能:SnapHelper。SnapHelper旨在支持RecyclerView的對齊方式,也就是通過計算對齊RecyclerView中TargetView 的指定點或者容器中的任何像素點。自定義一個SnapHelper挺麻煩的,還好android已經(jīng)為我們內(nèi)置好了兩個實現(xiàn): LinearSnapHelper & PagerSnapHelper。其中PagerSnapHelper真是我們需要的可以把RecyclerView改的像Viewpager的工具。
new PagerSnapHelper().attachToRecyclerView(mRecyclerView);

gif.gif

現(xiàn)在看著順暢多了:一次只能滑動一張圖片,停止的時候圖片的位置也對了。這樣一個基礎(chǔ)版的輪播圖就做成了。因為本質(zhì)是一個RecyclerView,我們可以RecyclerView.Itemanimator,來做出更多的動畫效果(這個我目前就不太會了(T_T))。最后奉上github地址,里面有更完整代碼,封裝了很多自定義屬性,歡迎star!

PS:進階版請戳:

用RecyclerView打造一個輪播圖(進階版)

總結(jié)

以上是生活随笔為你收集整理的用RecyclerView打造一个轮播图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。