1. 程式人生 > >Android關於小米相簿懸浮標題欄、凍結標題欄的實現方式(巢狀型RecycleView)

Android關於小米相簿懸浮標題欄、凍結標題欄的實現方式(巢狀型RecycleView)

效果圖如下:
這裡寫圖片描述

網上完全查詢不到關於凍結標題欄的實現方式,經過幾天的摸索嘗試,終於實現了這種效果;當然在過程中遇到了很多問題拖延了進度,關鍵是沒有摸清思路。

本文的實現方式已經盡了本人最大的能力進行簡化,並解決了快速滑動造成的錯亂問題,具體思路如下:
1.設定一個頂層的FrameLayout,用於裝載目標的標題欄TextView
2.設定兩個錨點,分別是uperPoint(0,0)和lowerPoint(0,textView.getHeight())通過getChildViewUnder()方法來判斷兩個點的view變化(getChildViewUnder()方法的介紹在本人的另一篇文章

關於 RecycleView 的findChildViewUnder()方法
3.針對滾動方向來對每個事件進行判斷,分別對標題欄TextView在頂層FrameLayout中進行移入移除的處理,就實現了標題欄凍結的效果

具體程式碼如下:
主檢視的佈局檔案:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width
="match_parent" android:layout_height="match_parent" tools:context="com.example.yuanh.fronzentitle.MainActivity">
<android.support.v7.widget.RecyclerView android:id="@+id/topRecycleView" android:layout_width="wrap_content" android:layout_height="wrap_content"
/>
<FrameLayout android:id="@+id/topContainer" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>

item項的佈局檔案:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:background="@color/colorPrimary"
        android:textSize="20sp"
        android:id="@+id/item_text"
        android:layout_width="match_parent"
        android:layout_height="30dp" />
    <com.example.yuanh.fronzentitle.MyRecycleView
    //注意這個paddingTop一定要和上面的標題欄的高度一致,為的是留出空白區
        android:paddingTop="30dp"
        android:id="@+id/itemGridView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none"/>
</FrameLayout>

MainActivity的關鍵程式碼部分:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initDate();
        final RecyclerView topView = (RecyclerView) findViewById(R.id.topRecycleView);
        topView.setLayoutManager(new LinearLayoutManager(this));
        topView.setAdapter(new TopAdapter(this));
//        選擇在滾動事件中判斷是否懸浮標題欄
        topView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            FrameLayout topContainer = (FrameLayout) findViewById(R.id.topContainer);
            int currentY;
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 60);
            FrameLayout preView = null;

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
//                分別設定兩個錨點
                FrameLayout currentUpView = (FrameLayout) recyclerView.findChildViewUnder(0, 0);
                FrameLayout currentLowView = (FrameLayout) recyclerView.findChildViewUnder(0, 60);
//                初始化preView
                if (dy == 0) {
                    preView = currentUpView;
                }

//                當下移到臨街點的時候,標題欄從原view中移到topContainer中
                if(currentLowView!=preView||dy>0){
                    TextView tv = (TextView)topContainer.getChildAt(0);
                    if (null!=tv) {
                        topContainer.removeView(tv);
                        params.gravity = Gravity.BOTTOM;
                        tv.setLayoutParams(params);
                        preView.addView(tv);
//                        將preView替換成現有的currentLowView
                        preView = currentLowView;
                    }
                }
//                當上移到臨界點時
                if (currentUpView!=preView||dy<0){
//                    上標題欄置底
                    TextView upTv = (TextView)currentUpView.findViewById(R.id.item_text);
                    if (null!=upTv){
                        params.gravity = Gravity.BOTTOM;
                        upTv.setLayoutParams(params);
                    }

//                    下標題欄置頂
                    TextView lowTv = (TextView)topContainer.getChildAt(0);
                    if (null!=lowTv){
                        topContainer.removeView(lowTv);
                        params.gravity = Gravity.TOP;
                        lowTv.setLayoutParams(params);
                        preView.addView(lowTv);
                    }

//                    將preView替換成現有的currentUpView
                    preView = currentUpView;
                }

//                只有一種情況會讓標題欄上浮,就是兩個錨點下的view相同的時候
                if (currentUpView.equals(currentLowView)){
                    TextView tv = (TextView)currentLowView.findViewById(R.id.item_text);
                    if (null!=tv){
                        currentUpView.removeView(tv);
                        params.gravity = Gravity.TOP;
                        tv.setLayoutParams(params);
                        topContainer.addView(tv);
                    }
                }
            }
        });
    }

好了,現在基本實現了小米相簿的凍結標題欄功能,要知道RecycleView的強大之處在於一個RecycleView就做出一個這樣的相簿,但實現懸浮標題欄可就不那麼簡單。接下來我會嘗試解決該問題,如果解決出來之後會下下一篇共享方法。如果各位大神有更好的方法,請賜教,感謝。

相關推薦

Android關於小米相簿懸浮標題凍結標題實現方式RecycleView

效果圖如下: 網上完全查詢不到關於凍結標題欄的實現方式,經過幾天的摸索嘗試,終於實現了這種效果;當然在過程中遇到了很多問題拖延了進度,關鍵是沒有摸清思路。 本文的實現方式已經盡了本人最大的能力進行簡化,並解決了快速滑動造成的錯亂問題,具體思路如下:

【PyQt5 學習記錄】005:QMainWindow 及狀態菜單和工具

qt5 open file statusbar ati etc con bubuko import 1 #!/usr/bin/env python 2 3 import sys 4 from PyQt5.QtWidgets import (QApplic

TP5 關聯模型使用關聯動態排序以及隱藏

在資料庫設計中,常常會有如下這種關聯模型,分類表中一條分類對應多個商品表中的商品 如果要獲得分類表中每條分類 以及 對應的商品的資訊,則需要先查詢分類表中的資料,然後根據結果遍歷查詢商品表,最後把資料拼接在一起 TP5中關聯模型可以解決這一問題 普通關聯 先建立分類表模型 Category.php

iOS導航狀態列及Tabbar高度區分iPhone X與其他iPhone機型

#define kIs_iphone (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) #define kIs_iPhoneX kScre

Android進階篇之ListViewGridView以及ScrollView實現按鈕控制滾動

這次還是一樣,因為專案需要,需要對滾動檢視需要手動控制,也就是點選上下左右按鈕,能讓滾動控制元件觸發對應的操作 在android中,滾動View最基本的有三種,分別是:ListView、GridView和ScrollView 先看效果圖:1、ListView的效果圖,右下角

Android中不同方向嵌套滑動的解決方式ListView為樣例

!= anim button wpa ktr text boolean adapter repeat 前言: 就像手機QQ的聊天消息列表。一個縱向滑動的ListView列舉全部消息,但每一條消息能夠橫向滑動。 而默認情況下,僅僅能有一個地方消化處理觸摸事件,要麽Lis

Android 仿 窗簾效果 和 登錄界面拖動效果 Scroller類的應用 附 2個DEMO及源代碼

@override 宋體 off down != 過程 事件 學習 border 在android學習中,動作交互是軟件中重要的一部分。當中的Scroller就是提供了拖動效果的類,在網上。比方說一些Launcher實現滑屏都能夠通過這個類去實現。以下要說的

Java多線程 —— 線程安全線程同步線程間通信含面試題集

err 線程等待 共同點 -c java多線 能夠 空間 而不是 不一致 一、線程安全 多個線程在執行同一段代碼的時候,每次的執行結果和單線程執行的結果都是一樣的,不存在執行結果的二義性,就可以稱作是線程安全的。 講到線程安全問題,其實是指多線程環境下對共享資源的訪問可能會

回車換行空格的ASCII碼值—附ASCII碼表

表示法 這就是 十六 就是 字符 編制 信息 閱讀 標準 回車、換行、空格的ASCII碼值 回車,ASCII碼13換行,ASCII碼10空格,ASCII碼32Return = CR = 13 = ‘\x0d‘NewLine = LF =

Android 音視頻深入 十 FFmpeg給視頻加特效附源碼下載

frame avi sca desc github cor 濾波器 struct find 項目地址,求starhttps://github.com/979451341/Audio-and-video-learning-materials/tree/master/FFmpe

Android 音視頻深入 十六 FFmpeg 推流手機攝像頭,實現直播 附源碼下載

音視頻 FFmpeg RTMP 直播 Android 源碼地址https://github.com/979451341/RtmpCamera/tree/master 配置RMTP服務器,雖然之前說了,這裏就直接粘貼過來吧 1.配置RTMP服務器 這個我不多說貼兩個博客分別是在mac和win

項目一:第十二天 1常見權限控制方式 2基於shiro提供url攔截方式驗證權限 3在realm中授權 5總結驗證權限方式四種 6用戶註銷7基於treegrid實現菜單展示

eal 重復數 規則 認證通過 delete get 數據庫 filter 登陸 1 課程計劃 1、 常見權限控制方式 2、 基於shiro提供url攔截方式驗證權限 3、 在realm中授權 4、 基於shiro提供註解方式驗證權限 5、 總結驗證權限方式(四種) 6、

RockBrain USB Server- 雲計算虛擬化USB設備集中管理遠程共享解決方案涉及銀企直聯

基本 私有雲 需要 14. 無需 計算虛擬化 大量 獨立 編碼算法 RockBrain USB Server- 雲計算虛擬化USB設備集中管理、遠程共享解決方案(涉及銀企直聯) 技術需求: 1.企業員工的大量USB Key,需要將key接入USB Server虛擬池,進行集

Android RxJava 實戰系列:優雅實現 網路請求回撥

轉自-----http://blog.csdn.net/carson_ho/article/details/78315696,請為大神打call 前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android

const修飾符const與指標一起使用C++學習筆記 6

一、 在C++中使用const修飾符來定義常量。(const來自單詞constant,是常量的意思) 用法:const 型別 常量名 = 表示式; 例如:const int LIMIT = 100; 這個常量LIMIT是有型別的,佔用儲存單元,有地址,可以用指標指向它,但不能修改它。

各個 C# 版本的主要特性釋出日期和釋出方式C# 1.0 - 7.3

原文 各個 C# 版本的主要特性、釋出日期和釋出方式(C# 1.0 - 7.3) 本文收集各個 C# 版本的主要特性、釋出日期和釋出方式。 C# 8.0 尚在預覽版本 C# 7.3 2018 年 5 月 隨 Visual Studio 2017 v15.7 釋出 C#

佈局的6種實現方式

1.利用浮動 <section class="layout float"> <style type="text/css"> .layout article div { height: 100px; } .layout.float .left

懸浮佈局的最差實現方式懸浮頭部實現,viewpager滑動

給部分程式碼看個大概實現,繼承 linearLayout,自己處理滑動,自己計運算元佈局中第一個佈局為摺疊部分。 其實,用scrollview,將listview以及懸浮部分高度設定為螢幕高度,效果直接,省事,滑動體驗更好。巢狀佈局也沒有滑動衝突 public class Scrollabl

13CentOS7 安裝Docker之擴充套件容器掛載主機目錄

容器掛載主機目錄   容器最強大的功能是它在遷移時能保持系統環境一致性。 不過有時候你不想把所有的檔案放進容器中。你可能想在容器之間共享一些大的檔案,或者單獨管理這些檔案。典型的例子是你希望容器訪問大型集中式資料庫,但是還希望其它客戶端也能與容器一起訪問。 解決方法是volumes

11CentOS7 安裝Docker之擴充套件儲存開發環境狀態

儲存開發環境狀態   如果你曾經開發過軟體,你可能至少一次地像這樣呼叫過,”奇怪了,之前明明正常的!”不過沒辦法快速地恢復到之前的正常狀態,你只能匆忙地去修改程式碼以儘快完成任務而不至於延期。這就浪費了許多時間。 版本控制軟體已經能幫助你快速恢復到指定的正常版本,不過但下面的兩個特