先上个图:
我所知道的有两种实现方式:
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>