Android tabLayout+recyclerView實現錨點定位

來源:互聯網
上載者:User

標籤:move   top   bar   smooth   bin   ges   status   scroll   可見   

原文連結:https://mp.weixin.qq.com/s/L3o2i3WTmg1ScXEYDS8YCg

在上一篇文章 Android 實現錨點定位中,我們介紹了tablayout+scrollView實現的錨點定位,今天我們使用tablayout+recyclerView 來實現同樣的效果。

實現思路

實現的思路與上一篇文章是一致的:
1、監聽recyclerView滑動到的位置,tablayout切換到對應標籤
2、tablayout各標籤點擊,recyclerView可滑動到對應地區

資料類比

資料類比,使用上一文章的AnchorView作為recyclerView的每個字view,同時這裡對recyclerView的最後一個子view的高度進行修改,讓其充滿螢幕。

private LinearLayoutManager manager;private String[] tabTxt = {"客廳", "臥室", "餐廳", "書房", "陽台", "兒童房"};//判讀是否是recyclerView主動引起的滑動,true- 是,false- 否,由tablayout引起的private boolean isRecyclerScroll;//記錄上一次位置,防止在同一內容塊裡滑動 重複定位到tablayoutprivate int lastPos;//用於recyclerView滑動到指定的位置private boolean canScroll;private int scrollToPosition;//tablayout設定標籤for (int i = 0; i < tabTxt.length; i++) {    tabLayout.addTab(tabLayout.newTab().setText(tabTxt[i]));}//計算內容塊所在的高度,全屏高度-狀態列高度-tablayout的高度(這裡固定高度50dp),用於recyclerView的最後一個item view填充高度int screenH = getScreenHeight();int statusBarH = getStatusBarHeight(this);int tabH = 50 * 3;int lastH = screenH - statusBarH - tabH;manager = new LinearLayoutManager(this);recyclerView.setLayoutManager(manager);recyclerView.setAdapter(new MyAdapter(this, tabTxt, lastH));@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {    holder.anchorView.setContentTxt(tabTxt[position]);    holder.anchorView.setAnchorTxt(tabTxt[position]);    //判斷最後一個view    if (position == tabTxt.length - 1) {        if (holder.anchorView.getHeight() < lastH) {            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);            params.height = lastH;            holder.anchorView.setLayoutParams(params);        }    }}
recyclerView滑動定位

recyclerView滑動引起的,addOnScrollListeneronScrolled的監聽第一個可見view的位置,直接將tablayout定位到相應的位置。

recyclerView.setOnTouchListener(new View.OnTouchListener() {    @Override    public boolean onTouch(View v, MotionEvent event) {        //當滑動由recyclerView觸發時,isRecyclerScroll 置true        if (event.getAction() == MotionEvent.ACTION_DOWN) {            isRecyclerScroll = true;        }        return false;    }});recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {    @Override    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {        super.onScrolled(recyclerView, dx, dy);        if (isRecyclerScroll) {            //第一個可見的view的位置,即tablayou需定位的位置            int position = manager.findFirstVisibleItemPosition();            if (lastPos != position) {                tabLayout.setScrollPosition(position, 0, true);            }            lastPos = position;        }    }});
tablayout切換定位

點擊tablayout進行切換,recyclerView需要滑動到相應的位置,注意這裡需要根據跳轉位置不同,進行相應的滑動。

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {    @Override    public void onTabSelected(TabLayout.Tab tab) {        //點擊標籤,使recyclerView滑動,isRecyclerScroll置false        int pos = tab.getPosition();        isRecyclerScroll = false;        moveToPosition(manager, recyclerView, pos);    }    @Override    public void onTabUnselected(TabLayout.Tab tab) {    }    @Override    public void onTabReselected(TabLayout.Tab tab) {    }});public void moveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int position) {    // 第一個可見的view的位置    int firstItem = manager.findFirstVisibleItemPosition();    // 最後一個可見的view的位置    int lastItem = manager.findLastVisibleItemPosition();    if (position <= firstItem) {        // 如果跳轉位置firstItem 之前(滑出螢幕的情況),就smoothScrollToPosition可以直接跳轉,        mRecyclerView.smoothScrollToPosition(position);    } else if (position <= lastItem) {        // 跳轉位置在firstItem 之後,lastItem 之間(顯示在當前螢幕),smoothScrollBy來滑動到指定位置        int top = mRecyclerView.getChildAt(position - firstItem).getTop();        mRecyclerView.smoothScrollBy(0, top);    } else {        // 如果要跳轉的位置在lastItem 之後,則先調用smoothScrollToPosition將要跳轉的位置滾動到可見位置        // 再通過onScrollStateChanged控制再次調用當前moveToPosition方法,執行上一個判斷中的方法        mRecyclerView.smoothScrollToPosition(position);        scrollToPosition = position;        canScroll = true;    }}recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {    @Override    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {        super.onScrollStateChanged(recyclerView, newState);        if (canScroll) {            canScroll = false;            moveToPosition(manager, recyclerView, scrollToPosition);        }    }});

至此,兩種實現錨點定位的方法就介紹到這裡,希望能協助到讀者在實際項目中的使用。
代碼與上一篇文章的在同一個git地址裡。

詳細代碼見
github地址:https://github.com/taixiang/tabScroll

歡迎關注我的部落格:https://blog.manjiexiang.cn/
更多精彩歡迎關注號:春風十裡不如認識你

有個「佛系碼農圈」,歡迎大家加入暢聊,開心就好!

到期了,可加我 tx467220125 拉你入群。

Android tabLayout+recyclerView實現錨點定位

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.