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>

关于AppBarLayout的五种ScrollFlags参考:
http://www.jianshu.com/p/7caa5f4f49bd

总结:

  • 对于需要跟着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的问题,即下拉的时候,页面还没完全拉下来就触发了刷新功能

此问题的解决参照:
http://blog.youkuaiyun.com/lvwenbo0107/article/details/51788601

我这里的解决:

第一步:实现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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦A梦z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值