1. 程式人生 > >Android 實現懸浮的幾種方式(一)AppBarLayout+PtrFrameLayout

Android 實現懸浮的幾種方式(一)AppBarLayout+PtrFrameLayout

先上個圖:
這裡寫圖片描述

我所知道的有兩種實現方式:

  • AppBarLayout巢狀控制滾動區實現(目前使用的)

  • 給RecyclerView增加HeaderView顯示隱藏切換實現

先把引用的包放出來:

compile 'com.android.support:cardview-v7:23.2.1'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.zhy:base-rvadapter:3.0.3'
compile 'com.zhy:base-adapter:3.0.3'
compile 'cn.finalteam.loadingviewfinal:ultra-pull-to
-refresh:1.0.1' compile 'cn.finalteam.loadingviewfinal:loading-more-view:1.0.1'

先說第一種吧(不需要headerview,上方佈局,下方recycleView):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools
="http://schemas.android.com/tools" android:id="@+id/stateView" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows
="true">
<android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp"> <!--需要跟著RecyclerView一起滾動的,設定 app:layout_scrollFlags="scroll|enterAlways"--> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layout_scrollFlags="scroll|enterAlways"> <include layout="@layout/layout_line" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:padding="@dimen/d_15dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="您已篩選" android:textColor="@color/gray_a" android:textSize="13sp" /> <TextView android:id="@+id/tv_time_result" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:text="今日" android:textColor="@color/gray_64" android:textSize="13sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="的生產裝箱情況" android:textColor="@color/gray_a" android:textSize="13sp" /> </LinearLayout> <include layout="@layout/layout_line" /> </LinearLayout> <!--放在layout的外面appbar的裡面就可以懸浮了 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:orientation="vertical" android:padding="@dimen/d_15dp"> <TextView android:id="@+id/tv_product_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/common_null" android:textColor="@color/gray_32" android:textSize="13sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingTop="29dp"> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <TextView android:id="@+id/tv_product_boxs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/common_null" android:textColor="@color/gray_32" android:textSize="28dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/d_10dp" android:text="箱" android:textColor="@color/gray_a" android:textSize="13sp" /> </LinearLayout> <TextView android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/lineColor" /> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <TextView android:id="@+id/tv_product_singles" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/common_null" android:textColor="@color/gray_32" android:textSize="28dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/d_10dp" android:text="單標" android:textColor="@color/gray_a" android:textSize="13sp" /> </LinearLayout> </LinearLayout> </LinearLayout> <include layout="@layout/layout_line" /> </android.support.design.widget.AppBarLayout> <cn.finalteam.loadingviewfinal.PtrClassicFrameLayout app:layout_behavior="@string/appbar_scrolling_view_behavior" android:id="@+id/ptr_rv_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:ptr_duration_to_close="300" app:ptr_duration_to_close_header="1500" app:ptr_keep_header_when_refresh="true" app:ptr_ratio_of_header_height_to_refresh="1.2" app:ptr_resistance="1.7"> <cn.finalteam.loadingviewfinal.RecyclerViewFinal android:id="@+id/rv_list" android:layout_width="match_parent" android:layout_height="match_parent" /> </cn.finalteam.loadingviewfinal.PtrClassicFrameLayout> </android.support.design.widget.CoordinatorLayout> </FrameLayout>

總結:

  • 對於需要跟著RecyclerView一起滾動消失的父佈局,設定 app:layout_scrollFlags="scroll|enterAlways;

  • 希望懸浮的,放在(滾動佈局)LinearLayout的外面AppBarLayout的裡面就可以懸浮了。

  • AppBarLayout裡面只存在2種佈局:滾動的和懸浮的

  • 對於滾動的主佈局裡面新增 app:layout_behavior="@string/appbar_scrolling_view_behavior"

這樣結束了,activity裡面正常載入RecyclerView就可以了

mRvList.setLayoutManager(new LinearLayoutManager(this));
mCommonAdapter = new CommonAdapter();
mRvList.setAdapter(mCommonAdapter);

這就簡單實現了懸浮的功能了。

但是我這裡加入了下拉重新整理的功能,出現了下拉重新整理先於AppbarLayout的問題,即下拉的時候,頁面還沒完全拉下來就觸發了重新整理功能

我這裡的解決:

第一步:實現OnOffsetChangedListener並重寫onOffsetChanged

public class BoxingProductChartActivity extends StateViewActivity implements AppBarLayout.OnOffsetChangedListener

第二步:當verticalOffset == 0,設定允許重新整理

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        if (verticalOffset == 0) {
            setCanRefresh(true);
        } else {
            setCanRefresh(false);
        }
    }
 private boolean canRefresh;
 public void setCanRefresh(boolean canRefresh) {
        this.canRefresh = canRefresh;
    }

第三步:設定給PtrClassicFrameLayout(下拉重新整理)

    @Bind(R.id.ptr_rv_layout)
    PtrClassicFrameLayout mPtrRvLayout;
        mPtrRvLayout.setOnRefreshListener(new OnDefaultRefreshListener() {

            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return canRefresh && OnDefaultRefreshListener.checkContentCanBePulledDown(frame, content, header);
            }

            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                requestData();
            }
        });

大功告成!就是圖中現在的情況了

附加:由於上方程式碼用到一些第三方庫,下面貼一個簡潔的。使用這種方式只要佈局調整好了就好了,不需要寫任何java程式碼的。。

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"-->
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        <!--注意點二:需要跟著RecyclerView一起滾動的,設定 app:layout_scrollFlags="scroll|enterAlways"-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:layout_scrollFlags="scroll|enterAlways">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="我是被滑動出去的view"
                android:textColor="@color/gray_a"
                android:textSize="13sp" />

        </LinearLayout>


        <!--注意點三:放在layout的外面appbar的裡面就可以懸浮了 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            android:orientation="vertical"
            android:padding="15dp">


            <TextView
                android:id="@+id/tv_product_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="我是懸浮-標題欄"
                android:textColor="@color/gray_32"
                android:textSize="13sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="我是懸浮-內容"
                android:textColor="@color/gray_a"
                android:textSize="13sp" />

        </LinearLayout>

        <include layout="@layout/layout_line" />


    </android.support.design.widget.AppBarLayout>

    <!-- 注意點四:app:layout_behavior="@string/appbar_scrolling_view_behavior" -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


</android.support.design.widget.CoordinatorLayout>