recyclerview+viewpager實現多分類fragment介面 仿京東分類介面
好久沒寫部落格了,今天決定寫一篇簡單的功能實現熱熱手
這是我2018年10月份在京東app錄製的他們的分類介面,今天主要就是實現這樣的一個分類的介面
整理思路
首先整理思路啊。整體介面的實現方式可能很多,但是需要儘可能的用簡單的方式,比如左邊的分類介面和右邊的一起看的話,好像用tablayout+viewpager也可以實現?雖然說他們都是垂直的,我們平時使用的是水平的,但是應該要實現的話也不是問題。
那這篇文章主要講解的是稍微簡單一點的,使用recyclerview+viewpager實現這個介面。
首先新建工程 匯入基本的包
implementation 'com.android.support:recyclerview-v7:27.1.1'
在確定了介面的佈局思路之後,首先看下我們的佈局檔案
首頁佈局
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:background="#ffffff" android:orientation="horizontal" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent"> <android.support.v7.widget.RecyclerView android:id="@+id/follow_category_rv" android:layout_width="63dp" android:layout_height="match_parent" android:layout_marginLeft="3dp" android:layout_marginTop="3dp"> </android.support.v7.widget.RecyclerView> <android.support.v4.view.ViewPager android:id="@+id/follow_fragment_viewpager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager> </LinearLayout> </android.support.constraint.ConstraintLayout>
很簡單啊,左邊一個recyclerview
右邊一個viewpager
接下來看下我們的邏輯程式碼
首頁程式碼
首先這裡要說下,左邊的分類很多情況下是通過介面得到資料後,在建立的,所以這裡我們使用一些假資料
private var mAdapter: CategoryRecyclerAdapter? = null private var mPagerAdapter: FragmentPagerAdapter? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //模擬假資料 真是開發中可能是通過介面得到 var list = mutableListOf<String>() for (i in 1..10) { list.add("test$i") } showCategory(list) } private fun showCategory(list: List<String>) { //給左邊的recyclerView設定資料和adapter mAdapter = CategoryRecyclerAdapter() follow_category_rv.adapter = mAdapter follow_category_rv.layoutManager = LinearLayoutManager(this) mAdapter?.setData(list) //給右邊的viewpager設定adapter mPagerAdapter = FragmentPagerAdapter(supportFragmentManager, list) follow_fragment_viewpager.adapter = mPagerAdapter //recyclerView的item點選事件 mAdapter?.listener = { _, position -> follow_fragment_viewpager.currentItem = position } }
好久沒用MK寫部落格了,為什麼程式碼模組都是紅色的。。
看下上面的程式碼 很簡單,我也加了一些註釋
關於一些adapter的程式碼 我會在文末給連結。
先來看看效果
啊看起來還不錯啊,但是viewpager是左右滑動的。而且左右滑動viewpager左邊的分類也會變,這樣好像有點奇怪。
我們接下來開始優化一下
首先來一個viewpager切換動畫。
viwepager切換動畫程式碼
/**
* introduce:這裡寫介紹
* createBy:sunwentao
* email:[email protected]
* time: 9/10/18
*/
class DefaultTransformer : ViewPager.PageTransformer {
override fun transformPage(view: View, position: Float) {
var alpha = 0f
if (position in 0.0..1.0) {
alpha = 1 - position
} else if (-1 < position && position < 0) {
alpha = position + 1
}
view.alpha = alpha
view.translationX = view.width * -position
val yPosition = position * view.height
view.translationY = yPosition
}
}
給我們的viewpager設定上看看效果
follow_fragment_viewpager.setPageTransformer(true, DefaultTransformer())
看起來還不錯啊
但是響應viewpager的滑動事件還是左右,現在的gif圖我是操作的左邊的分類,右邊的viewpager響應,如果反過來,viewpager切換還是需要左右滑動,這當然還是不行的。
ps: 有的人不需要viewpager能手動切換,只需要點選點選分類切換
上下滑動的viewpager
/**
* introduce:這裡寫介紹
* createBy:sunwentao
* email:[email protected]
* time: 9/10/18
*/
class VerticalViewPager : ViewPager {
private var noScroll = false
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
private fun swapTouchEvent(event: MotionEvent): MotionEvent {
val width = width.toFloat()
val height = height.toFloat()
event.setLocation(event.y / height * width, event.x / width * height)
return event
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return super.onInterceptTouchEvent(swapTouchEvent(MotionEvent.obtain(event)))
}
override fun onTouchEvent(ev: MotionEvent): Boolean {
return if (noScroll)
false
else
super.onTouchEvent(swapTouchEvent(MotionEvent.obtain(ev)))
}
//如果你想要你的viewpager不要響應滑動 設定這個為true 同時註釋掉onInterceptTouchEvent方法
fun setNoScroll(noScroll: Boolean) {
this.noScroll = noScroll
}
}
首先看下程式碼這是我在網上找到的一個別人的實現方式,通過重寫viewpager的這些方法,你就能得到如下的一個上下的viewpager。同時我在裡面加了一個方法setNoScroll,注意看註釋。這個是用來操作viewpager不響應滑動事件用的
到這裡 好像差不多結束了
最後還是提一嘴
如果你的右側的fragment是帶有上拉載入更多的網我建議
有倆種實現方法
1,簡單的實現就是靜止viewpager滑動,只能通過左邊的分類來控制。這樣右邊fragment中的操作是完全沒問題的,