1. 程式人生 > >recyclerview+viewpager實現多分類fragment介面 仿京東分類介面

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中的操作是完全沒問題的,