Android仿微信讀書傳送帶列表功能
實(shí)現(xiàn)效果

使用
<com.icool.carousel_lib.CarouselLayoutandroid:id="@+id/carousel"android:layout_width="match_parent"android:layout_height="match_parent"app:carousel_angle="-30"app:carousel_spacing="20dp"app:carousel_speed="1" />
只需要通過設(shè)置Adapter就OK了
public void setAdapter(RecyclerView.Adapter adapter1, RecyclerView.Adapter adapter2, RecyclerView.Adapter adapter3) {mRv1.setAdapter(adapter1);mRv2.setAdapter(adapter2);mRv3.setAdapter(adapter3);}
屬性說明
| 屬性值 | 說明 | 值 |
|---|---|---|
| carousel_angle | 傾斜角度 | 默認(rèn)-30° |
| carousel_spacing | 列表之間的間隙,通常設(shè)置為recyclerView的item間距大小一致 | dp |
| carousel_speed | 速度,值越大傳送越快,不小于0 | 默認(rèn)1 |
可在代碼中設(shè)置間隙 setGapSpacing
代碼中設(shè)置角度 setAngle
代碼中設(shè)置速度 setSpeed
需求分析
直觀有 三條傳送帶式列表
一個(gè)正向移動(dòng) 兩個(gè)反向移動(dòng)
有一個(gè)傾斜角度
可以循環(huán)展示
具體分析
根據(jù)樣式 可以確定的是需要自定義ViewGroup來實(shí)現(xiàn)
結(jié)合列表的正向反向移動(dòng) 可以確定:RecyclerView + LinearLayoutManager 可以做到
不停滾動(dòng)借助 Scroller 來實(shí)現(xiàn)
傾斜角度 可以通過 setRatation() 方法來旋轉(zhuǎn)一個(gè)角度
循環(huán)展示 通過設(shè)置 RecyclerView.Adapter的 itemCount 為 Inter.MAX_VALUE
具體實(shí)現(xiàn)
自定義CarouselLayout繼承自ViewGroup
添加一個(gè)子View LinearLayout,
setOrientation(LinearLayout.VERTICAL);
依次添加三個(gè) RecyclerView,設(shè)置其 marginTop為 gapSpacing的值
mContainer = new LinearLayout(getContext());mContainer.setOrientation(LinearLayout.VERTICAL);addView(mContainer, generateDefaultLayoutParams());mRv1 = new CarouselRecyclerView(getContext());mRv2 = new CarouselRecyclerView(getContext());mRv3 = new CarouselRecyclerView(getContext());mContainer.addView(mRv1);mContainer.addView(mRv2);mContainer.addView(mRv3);setSpacing();//此方法設(shè)置margin,詳見代碼mRv1.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));mRv2.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, true));mRv3.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
旋轉(zhuǎn)一個(gè)角度
設(shè)置 LinearLayout 的rotation
mContainer.setRotation(mAngle);//旋轉(zhuǎn)角度設(shè)置LinearLayout的大小來保證切斜后仍可以占滿全屏
由于在ViewGroup中最大的距離就是對角線,所以 設(shè)置 子View的寬高都為對角線的長度
//對角線長度mDiagonalLine = (int) Math.sqrt(getMeasuredWidth() * getMeasuredWidth() + getMeasuredHeight() * getMeasuredHeight());ViewGroup.LayoutParams params = mContainer.getLayoutParams();params.width = mDiagonalLine;params.height = mDiagonalLine;mContainer.setLayoutParams(params);
移動(dòng)起來
借助Scroller類來不斷 調(diào)用 computeScroll方法實(shí)現(xiàn)滾動(dòng)
@Overridepublic void computeScroll() {super.computeScroll();mRv1.scrollBy(mSpeed, 0);//speed 對應(yīng)移動(dòng)像素值mRv2.scrollBy(-mSpeed, 0);mRv3.scrollBy(mSpeed, 0);if (mScroller.isFinished()) {start();}}
其他
因?yàn)榱斜硎褂肦ecyclerView實(shí)現(xiàn),所以我們手動(dòng)還可以滑動(dòng)它。
如果不想手動(dòng)滑動(dòng)的話,重寫RecyclerView的onTouchEvent方法, return false;無限循環(huán)
設(shè)置Adapter的時(shí)候
@Overridepublic int getItemCount() {return Integer.MAX_VALUE;}
然后在 onBindViewHolder 方法取item的時(shí)候 進(jìn)行取余操作
String url = mSources[position % mSources.length];這個(gè)效果在微信閱讀上是WebView實(shí)現(xiàn)的,我們的UI直接抄了過來。所以只能用Android代碼實(shí)現(xiàn)一下。
需要源碼的童鞋可以在公眾號對話框回復(fù)【微信讀書】即可獲取哦!
到這里就結(jié)束啦。
