在使用CoordinatorLayout布局时,想在NestedScrollView里嵌套RecyclerView来加载网络数据来形成顶部AppBarLayout跟随NestedScrollView移动的效果,效果如下所示。
布局代码如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/Srl_Doc"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srlPrimaryColor="@color/colorNull"
app:srlAccentColor="@color/colorPink"
app:srlEnablePreviewInEditMode="true"
app:srlEnableHeaderTranslationContent="false"
>
<android.support.design.widget.CoordinatorLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/Ab_Layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collpasing_toolbar_layout"
app:contentScrim="#8BC34A"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:collapsedTitleGravity="center"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
android:fitsSystemWindows="true"
>
<include
android:scaleType="fitXY"
app:layout_collapseMode="parallax"
android:contentDescription="TODO"
android:fitsSystemWindows="true"
android:id="@+id/doc_list_top_bar"
layout="@layout/doc_list_top_bar" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
android:theme="@style/MyToolbarTheme"
app:contentInsetStartWithNavigation="0dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/OverFlowMenyTheme"
>
<android.support.v7.widget.ActionMenuView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<android.support.v7.widget.RecyclerView
app:layout_constraintTop_toBottomOf="@+id/Ab_Layout"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/Rv_Doc"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</LinearLayout>
这样做就有一个问题,NestedScrollView嵌套RecyclerView会导致RecyclerView每次加载新数据时,都会从头开始一次性调用全部onCreateViewHolder和onBindViewHolder来绑定数据。
数据小的时候没什么事,数据多的时候就会OOM了。。。
经过三天各种焦头烂额的查阅请教测试,终于解决了这个问题。
下面是新布局。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/Srl_Doc"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:srlPrimaryColor="@color/colorNull"
app:srlAccentColor="@color/colorPink"
app:srlEnablePreviewInEditMode="true"
app:srlEnableHeaderTranslationContent="false"
>
<com.scwang.smartrefresh.header.BezierCircleHeader
android:background="@color/colorNull"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.scwang.smartrefresh.layout.footer.BallPulseFooter
app:srlAnimatingColor="@color/colorPink"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.design.widget.CoordinatorLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/Ab_Layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collpasing_toolbar_layout"
app:contentScrim="#8BC34A"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:collapsedTitleGravity="center"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
android:fitsSystemWindows="true"
>
<include
app:layout_collapseMode="parallax"
android:contentDescription="TODO"
android:fitsSystemWindows="true"
android:id="@+id/doc_list_top_bar"
android:adjustViewBounds="true"
layout="@layout/doc_list_top_bar" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
android:theme="@style/MyToolbarTheme"
app:contentInsetStartWithNavigation="0dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/OverFlowMenyTheme"
>
<android.support.v7.widget.ActionMenuView
android:id="@+id/amv"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/Fl_Layout"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.widget.NestedScrollView>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</FrameLayout>
改动不大,就是把NestedScrollView嵌套RecyclerView换成了FrameLayout嵌套NestedScrollView,然后把FrameLayout写成fragment ,RecyclerView在fragment里面初始化和加载。
<?xml version="1.0" encoding="utf-8"?>
<!--RecyclerView单独抽出来放一个xml文件里面 ,我这里是doc_fragment.xml-->
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.RecyclerView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/Rv_Doc"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
//RecyclerView在fragment里面初始化和刷新布局
public class Doc_Fragment extends BaseFragment implements DetailPageDocList.OnTriggerListener{
@Bind(R.id.Rv_Doc)
RecyclerView RvDoc;
private DetailPageDocListAdapter adapter;
private List<BilibiliAlbum.DataBean.ItemsBean> items = new ArrayList<>();
@Override
public View initView() {
View view = View.inflate(mContext, R.layout.doc_fragment, null);
System.out.println("Fragment初始化布局成功");
return view;
}
@Override
public void initData() {
super.initData();
System.out.println("Fragment初始化数据成功");
}
public void initRvDoc(List<BilibiliAlbum.DataBean.ItemsBean> items){
this.items.clear();
this.items.addAll(items);
adapter = new DetailPageDocListAdapter(mContext,this.items);
//记得写上manager
LinearLayoutManager manager = new LinearLayoutManager(mContext);
RvDoc.setLayoutManager(manager);
RvDoc.setAdapter(adapter);
}
public void notifyRvDoc(List<BilibiliAlbum.DataBean.ItemsBean> items){
this.items.addAll(items);
System.out.println("**********************DttailPageDocList的items是 " + this.items.size());
adapter.setDataBean(this.items);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO: inflate a fragment view
View rootView = super.onCreateView(inflater, container, savedInstanceState);
ButterKnife.bind(this, rootView);
return rootView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
@Override
public void onTrigger(List<BilibiliAlbum.DataBean.ItemsBean> items, int i) {
if (i == 0){
//刷新
initRvDoc(items);
}
if (i == 1){
//加载
notifyRvDoc(items);
}
}
}
在Activity里面把布局文件里的FrameLayout初始化成Fragment,通过接口回调传递数据给Fragment。
private void setInitFragment() {
Doc_Fragment baseFragment = new Doc_Fragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.Fl_Layout, baseFragment);
transaction.commit();
}
可以看到RecyclerView的复用机制能实现了。