RecyclerView 簡單實現(xiàn)章節(jié)列表

Animation.gif

在開發(fā)項目的時候,很多時候都需要用到上圖這種功能, 章節(jié)列表。 但坑爹的是,這種控件在ios中原生自帶, 但android卻沒有自帶。這時候又不免去github里面去找一些開源庫。所以說, 開發(fā)android的同學需要做各種ios的特效。

![H$RK3[L)N}]%$RX5HK)HTG.gif

github這種開源庫灰常多,但開源庫畢竟是別人的,能自己弄出來當然是最好的。下面我就分享下我的實現(xiàn)思路。

功能需求:
1.章節(jié)標題欄需要固定在頂部。
2.固定的章節(jié)標題欄可以隨著列表的章節(jié)標題欄進行相應(yīng)的移動。

實現(xiàn):
1.固定章節(jié)欄: 采用famelayout布局, 在RecyclerView 外層添加一個章節(jié)欄標題,一直固定在頂部。
2.固定章節(jié)欄隨列表章節(jié)欄移動:當判斷下個進入頂部是列表章節(jié)標題的時候 ,對固定章節(jié)欄進行相應(yīng)的布局調(diào)整。

主要的實現(xiàn)代碼:

public class SectionRecyclerActivity extends AppCompatActivity {

    ..........

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      ..........

        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                int position = (mLayoutManager.findFirstVisibleItemPosition() < 0) ? 0 : mLayoutManager.findFirstVisibleItemPosition();
                int totalSize = mLayoutManager.getItemCount();
                if (mAdapter.getItemViewType(position) == TITLE_TYPE) {
                    mTopTitle.setText(mDatas.get(position).content);
                }
                int nextPosition = position + 1;
                if (nextPosition < totalSize) {
                    //獲取下個章節(jié)標題的位置, 如果小于0說明后面沒有章節(jié)標題。 如果下個章節(jié)標題位置還未顯示出來,也不用做改變。
                    int sectionPosition = findNextSection(nextPosition, totalSize);
                    if (sectionPosition < 0 || sectionPosition > (position + mRecyclerView.getChildCount() - 1)) {
                        refreshTopTitle();
                        return;
                    }

                    //獲取下一個章節(jié)標題的top, 如果top 大于 展示label的高度, 無須做改動。
                    int nextTopMargin = mLayoutManager.findViewByPosition(sectionPosition).getTop();
                    if (nextTopMargin < mMaxHeight) {
                        mTopTitleLayoutParams.topMargin = -(mMaxHeight - nextTopMargin);
                        mTopTitle.setLayoutParams(mTopTitleLayoutParams);
                        //如果當前第一個顯示的不是章節(jié)標題, 需要顯示上一個章節(jié)標題
                        if (mAdapter.getItemViewType(position) != TITLE_TYPE) {
                            mTopTitle.setText(findPreSectionText(position));
                        }
                    } else {
                        refreshTopTitle();
                    }
                }
            }
        });
    }

    private void refreshTopTitle() {
        if (mTopTitleLayoutParams.topMargin == 0) return;
        mTopTitleLayoutParams.topMargin = 0;
        mTopTitle.setLayoutParams(mTopTitleLayoutParams);
    }

    private int findNextSection(int position, int size) {
        for (; position < size; position++) {
            if (mAdapter.getItemViewType(position) == TITLE_TYPE) return position;
        }
        return -1;
    }

    private String findPreSectionText(int position) {
        for (; position > -1; position--) {
            if (mAdapter.getItemViewType(position) == TITLE_TYPE) return mDatas.get(position).content;
        }
        return "";
    }

    private boolean isInit = false;

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        //當activity可以獲取焦點的時候,獲取固定標題欄的高度
        if (hasFocus && !isInit) {
            isInit = true;
            mMaxHeight = mTopTitle.getHeight();
        }
    }
..........
}

這里是主要實現(xiàn)邏輯的代碼,主要是監(jiān)聽recyclerView的滾動事件對固定標題欄做相應(yīng)的操作。
這里暫且只支持recylerView的垂直的線性布局。像瀑布和網(wǎng)格布局現(xiàn)在還沒有支持。
完整的代碼:https://github.com/hu5080126/SimpleExample/tree/master/sectionRecyclerView/src

各位同學如果還有什么更好的實現(xiàn)方式,歡迎留言!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容