在日常Android
列表开发当中,我们可能会遇到以下的需求:
我们在滑动列表的时候,头部View置顶不可以滑动.
我刚好看到有一个开源库可以帮我们快速实现,分享出来希望能提高看文章的小伙伴的开发效率.
StickyItemDecoration
StickyItemDecoration
有两个特性:
- 粘性头部是放置在RecyclerView外面的View,对比之前绘制出来的粘性头部,能显示出点击的效果,并且处理点击事件更加简单;
- 不需要频繁的创建粘性头部的View用于绘制,只需要刷新外置的粘性头部的数据即可。
导入项目
开源库的作者没有生成远程依赖的,所以需要我们clone
,这样也可以方便在开源库的基础上扩展一些自己想要的东西。
请自行查看开源库详情代码
效果图有点不方便展示,感兴趣的小伙伴请自行查看。
代码实现
StickyHeadContainer
用来承载粘性头部布局,并且需要和RecyclerView的顶部对齐:
<RelativeLayout
android:id="@+id/content_main"
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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.oubowu.stickydemo.MainActivity"
tools:showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_margin="10dp"
tools:background="@color/colorAccent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</android.support.v7.widget.RecyclerView>
<com.oubowu.stickyitemdecoration.StickyHeadContainer
android:id="@+id/shc"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="wrap_content">
<include
layout="@layout/item_stock_sticky_head"/>
</com.oubowu.stickyitemdecoration.StickyHeadContainer>
</RelativeLayout>
RecyclerView只需要添加一个StickyItemDecoration即可实现粘性头部,需要传入StickyHeadContainer用于头部的处理,以及粘性头部的类型;然后头部的点击处理就像平常一样处理
final StickyHeadContainer container = (StickyHeadContainer) findViewById(R.id.shc);
final TextView tvStockName = (TextView) container.findViewById(R.id.tv_stock_name);
final CheckBox checkBox = (CheckBox) container.findViewById(R.id.checkbox);
final ImageView more = (ImageView) container.findViewById(R.id.iv_more);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mAdapter.getData().get(mStickyPosition).getData().check = isChecked;
mAdapter.notifyItemChanged(mStickyPosition);
}
});
container.setDataCallback(new StickyHeadContainer.DataCallback() {
@Override
public void onDataChange(int pos) {
mStickyPosition = pos;
StockEntity.StockInfo item = mAdapter.getData().get(pos).getData();
tvStockName.setText(item.stickyHeadName);
checkBox.setChecked(item.check);
}
});
more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "点击了粘性头部的更多", Toast.LENGTH_SHORT).show();
}
});
container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "点击了粘性头部:" + tvStockName.getText(), Toast.LENGTH_SHORT).show();
}
});
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false));
mRecyclerView.addItemDecoration(new StickyItemDecoration(container, RecyclerViewAdapter.TYPE_STICKY_HEAD));
mRecyclerView.addItemDecoration(new SpaceItemDecoration(mRecyclerView.getContext()));
Adapter需要重写这两个方法,用于处理GridLayoutManager和StaggeredGridLayoutManager模式下的头部使之占满一行:
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
FullSpanUtil.onAttachedToRecyclerView(recyclerView, this, TYPE_STICKY_HEAD);
}
@Override
public void onViewAttachedToWindow(RecyclerViewHolder holder) {
super.onViewAttachedToWindow(holder);
FullSpanUtil.onViewAttachedToWindow(holder, this, TYPE_STICKY_HEAD);
}
网友评论