RecyclerView 过滤数据(既能显示全部数据又能显示过滤后的数据)
最近在项目中遇到这么一个需求:用一个列表加载所有的消息数据,有两个按钮,一个按钮点击了显示全部消息的列表,一个按钮点击了显示未读消息的列表。
思路:过滤器
过滤条件
1.首先是recyclerview 的适配器 要备份原来的数据并且要实现 implementsFilterable
private List mDataList;
private List backData;//用来备份原始数据
private CheckBox cb_quanxuan;
private NewsFilter newsFilter;
public NormalRecyclerViewAdapter(Context mContext, List mDataList, CheckBox cb_quanxuan) {
this.mContext = mContext;
this.mDataList = mDataList;
this.cb_quanxuan = cb_quanxuan;
mInflater = LayoutInflater.from(mContext);
backData=mDataList;
}
@Override
public Filter getFilter() {
if (newsFilter ==null){
newsFilter = new NewsFilter();
}
return newsFilter;
}
private class NewsFilter extends Filter{
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults result = new FilterResults();
List list = null;
if (TextUtils.isEmpty(charSequence)){//当过滤的关键字为空的时候,我们则显示所有的数据
list = backData;
}else if (charSequence.equals("1")){
//显示全部
list=backData;
}else if (charSequence.equals("0")){
//显示未读
list = new ArrayList();
for (AllNotification.ResultBean recomend:backData){
if (recomend.getStatus().equals("1")){
list.add(recomend);
}
}
}
result.values = list; //将得到的集合保存到FilterResults的value变量中
result.count = list.size();//将集合的大小保存到FilterResults的count变量中
return result;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
mDataList = (List)filterResults.values;
if (filterResults.count>0){
notifyDataSetChanged();//通知数据发生了改变
}/*else {
notifyDataSetInvalidated();//通知数据失效
LogUtil.d("publishResults:notifyDataSetInvalidated");
}*/
}
}
RxView.clicks(tv_xianshiquanbu).throttleFirst(2,TimeUnit.SECONDS).subscribe(new Action1() {
@Override
public void call(Void aVoid) {
tv_xianshiquanbu.setTextColor(Color.parseColor("#888888"));
tv_xianshiweidu.setTextColor(Color.parseColor("#cccccc"));
mAdapter.getFilter().filter("1");
}
});
RecyclerView 对数据进行分类
1.重写getItemViewType方法
@Override
public int getItemViewType(int position) {
if (mDataList != null && mDataList.get(position).getCataid().equals("4")) {
return ORIGINAL;
} else {
return FORWARD;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType==ORIGINAL){
return new DynamicViewHolder(mInflater.inflate(R.layout.item_dongtai_yuanchuang, parent, false), viewType, 0);
}else{
return new ZhuanViewHolder(mInflater.inflate(R.layout.item_dongtai, parent, false), viewType, 0);
}
}
HeaderViewListAdapter
package costomview.mycustomrecyclerview;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HeaderViewListAdapter;
import adapter.CommonViewHolder;
/**
* Created by Administrator on 2017/4/19 0019.
*/
public class WrapRecyclerAdapter extends RecyclerView.Adapter {
private static final String TAG = "WrapRecyclerAdapter";
private SparseArray mHeaderViews;
private SparseArray mFooterViews;
//头部开始的位置
private static int BASE_ITEM_TYPE_HEADER = 10000000;
//底部开始的位置
private static int BASE_ITEM_TYPE_FOOTER = 20000000;
//数据列表的adpter不包含头部与底部
private RecyclerView.Adapter mAdapter;
public WrapRecyclerAdapter(RecyclerView.Adapter mAdapter) {
this.mAdapter = mAdapter;
mHeaderViews = new SparseArray();
mFooterViews = new SparseArray();
}
/**
*
* @param parent
* @param viewType 从getItemViewType获取
* @return
*/
@Override
public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//区分头部与底部和中间数据
if (mHeaderViews.indexOfKey(viewType)>=0){
//头部
View headerView=mHeaderViews.get(viewType);
return createHeaderViewHolder(headerView);
}else if (mFooterViews.indexOfKey(viewType)>=0){
//底部
View footerView=mFooterViews.get(viewType);
return createFooterViewHolder(footerView);
}else{
//中间的数据列表
return (CommonViewHolder) mAdapter.onCreateViewHolder(parent,viewType);
//return mAdapter.createViewHolder(parent,viewType);
}
}
private CommonViewHolder createFooterViewHolder(View footerView) {
/* return new RecyclerView.ViewHolder(footerView) {
};*/
return new CommonViewHolder(footerView);
}
private CommonViewHolder createHeaderViewHolder(View headerView) {
/* return new RecyclerView.ViewHolder(headerView) {
};*/
return new CommonViewHolder(headerView);
}
@Override
public void onBindViewHolder(CommonViewHolder holder, int position) {
int numHeaders = mHeaderViews.size();
if (position < numHeaders) {
//是头部不需要绑定数据
return;
}
if (position>=(mHeaderViews.size()+mAdapter.getItemCount())){
//此时为底部
return;
}
// 返回列表Adapter的getItemViewType
position = position - mHeaderViews.size();
mAdapter.onBindViewHolder(holder, position);
/* // int numFooters=
//判断是否是中间的key
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getItemCount();
if (adjPosition < adapterCount) {
mAdapter.bindViewHolder(holder,adjPosition);
}
}*/
//底部
// return mFooterViews.keyAt(adjPosition - adapterCount);
}
@Override
public int getItemCount() {
return mHeaderViews.size()+mAdapter.getItemCount()+mFooterViews.size();
}
/**
* 添加头部
* @param view*/
public void addHeaderView(View view) {
if (mHeaderViews.indexOfValue(view)==-1){
//判断是否已经添加了这个头部的View
//如果存在就不要重复添加了
mHeaderViews.put(BASE_ITEM_TYPE_HEADER++,view);
}
notifyDataSetChanged();
}
/**
* 移除头部
* @param view
*/
public void removeHeaderView(View view){
if (mHeaderViews.indexOfValue(view)>=0){
mHeaderViews.removeAt(mHeaderViews.indexOfValue(view));
}
notifyDataSetChanged();
}
/**
* 加载底部
* @param view
*/
public void addFooterView(View view){
if (mFooterViews.indexOfValue(view)==-1){
//判断底部是否包含这个底部的View
//如果包含就不要重复添加了
mFooterViews.put(BASE_ITEM_TYPE_FOOTER++,view);
}
notifyDataSetChanged();
}
public void removeFooterView(View view){
if (mFooterViews.indexOfValue(view)>=0){
mFooterViews.removeAt(mFooterViews.indexOfValue(view));
}
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
//根据当前位置,确定头部 底部 还是 列表
//判断是否为头部
int numHeaders = mHeaderViews.size();
if (position < numHeaders) {
return mHeaderViews.keyAt(position);//返回的是头部的key
}
/* if (position>=(mHeaderViews.size()+mAdapter.getItemCount())){
//此时为底部
// 直接返回position位置的key
position = position - mHeaderViews.size() - mAdapter.getItemCount();
return mFooterViews.keyAt(position);
}*/
//判断是否是中间的key
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getItemCount();
if (adjPosition < adapterCount) {
return mAdapter.getItemViewType(adjPosition);
}
}
//底部
return mFooterViews.keyAt(adjPosition - adapterCount);
}
public void adjustSpanSize(RecyclerView recycler) {
if (recycler.getLayoutManager() instanceof GridLayoutManager) {
final GridLayoutManager layoutManager = (GridLayoutManager) recycler.getLayoutManager();
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
boolean isHeaderOrFooter =
isHeaderPosition(position) || isFooterPosition(position);
return isHeaderOrFooter ? layoutManager.getSpanCount() : 1;
}
});
}
}
/**
* 是不是底部位置
*/
private boolean isFooterPosition(int position) {
return position >= (mHeaderViews.size() + mAdapter.getItemCount());
}
/**
* 是不是头部位置
*/
private boolean isHeaderPosition(int position) {
return position < mHeaderViews.size();
}
}
List testList=new ArrayList();
for (int i = 0; i < 10; i++) {
testList.add("item"+i);
}
adapter=new AllEBoardPreviewAdapter(testList);
WrapRecyclerAdapter wrapRecyclerAdapter=new WrapRecyclerAdapter(adapter);
rvEpreview.setAdapter(wrapRecyclerAdapter);
wrapRecyclerAdapter.addHeaderView(LayoutInflater.from(AllEboradPreviewActivity.this).inflate(R.layout.test_header,null));
wrapRecyclerAdapter.addFooterView(LayoutInflater.from(AllEboradPreviewActivity.this).inflate(R.layout.test_footer,null));
package costomview.mycustomrecyclerview;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Administrator on 2017/4/19 0019.
*/
public class WrapRecyclerView extends RecyclerView {
// private WrapRecyclerAdapter mAdapter;
// 包裹了一层的头部底部Adapter
private WrapRecyclerAdapter mWrapRecyclerAdapter;
// 这个是列表数据的Adapter
private RecyclerView.Adapter mAdapter;
private AdapterDataObserver mAdapterDataObserver = new AdapterDataObserver() {
@Override
public void onChanged() {
if (mAdapter == null) return;
// 观察者 列表Adapter更新 包裹的也需要更新不然列表的notifyDataSetChanged没效果
if (mWrapRecyclerAdapter != mAdapter)
mWrapRecyclerAdapter.notifyDataSetChanged();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
if (mAdapter == null) return;
// 观察者 列表Adapter更新 包裹的也需要更新不然列表的notifyDataSetChanged没效果
if (mWrapRecyclerAdapter != mAdapter)
mWrapRecyclerAdapter.notifyItemRemoved(positionStart);
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
if (mAdapter == null) return;
// 观察者 列表Adapter更新 包裹的也需要更新不然列表的notifyItemMoved没效果
if (mWrapRecyclerAdapter != mAdapter)
mWrapRecyclerAdapter.notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
if (mAdapter == null) return;
// 观察者 列表Adapter更新 包裹的也需要更新不然列表的notifyItemChanged没效果
if (mWrapRecyclerAdapter != mAdapter)
mWrapRecyclerAdapter.notifyItemChanged(positionStart);
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
if (mAdapter == null) return;
// 观察者 列表Adapter更新 包裹的也需要更新不然列表的notifyItemChanged没效果
if (mWrapRecyclerAdapter != mAdapter)
mWrapRecyclerAdapter.notifyItemChanged(positionStart,payload);
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
if (mAdapter == null) return;
// 观察者 列表Adapter更新 包裹的也需要更新不然列表的notifyItemInserted没效果
if (mWrapRecyclerAdapter != mAdapter)
mWrapRecyclerAdapter.notifyItemInserted(positionStart);
}
};
public WrapRecyclerView(Context context) {
super(context);
}
public WrapRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public WrapRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setAdapter(Adapter adapter) {
// 为了防止多次设置Adapter
if (mAdapter != null) {
mAdapter.unregisterAdapterDataObserver(mAdapterDataObserver);
mAdapter = null;
}
this.mAdapter = adapter;
if (adapter instanceof WrapRecyclerAdapter) {
mWrapRecyclerAdapter = (WrapRecyclerAdapter) adapter;
} else {
mWrapRecyclerAdapter = new WrapRecyclerAdapter(adapter);
}
super.setAdapter(mWrapRecyclerAdapter);
// 注册一个观察者
mAdapter.registerAdapterDataObserver(mAdapterDataObserver);
// 解决GridLayout添加头部和底部也要占据一行
mWrapRecyclerAdapter.adjustSpanSize(this);
}
/**
* 添加头部
*
* @param view
*/
public void addHeaderView(View view) {
if (mWrapRecyclerAdapter != null) {
mWrapRecyclerAdapter.addHeaderView(view);
}
}
/**
* 移除头部
*
* @param view
*/
public void removeHeaderView(View view) {
if (mWrapRecyclerAdapter != null) {
mWrapRecyclerAdapter.removeHeaderView(view);
}
}
/**
* 加载底部
*
* @param view
*/
public void addFooterView(View view) {
if (mWrapRecyclerAdapter != null) {
mWrapRecyclerAdapter.addFooterView(view);
}
}
public void removeFooterView(View view) {
if (mWrapRecyclerAdapter != null) {
mWrapRecyclerAdapter.removeFooterView(view);
}
}
}
rvEpreview.setLayoutManager(new LinearLayoutManager(this));
// rvEpreview.setAdapter(adapter);
List testList=new ArrayList();
for (int i = 0; i < 10; i++) {
testList.add("item"+i);
}
adapter=new AllEBoardPreviewAdapter(testList);
rvEpreview.setAdapter(adapter);
rvEpreview.addHeaderView(LayoutInflater.from(AllEboradPreviewActivity.this).inflate(R.layout.test_header,null));
rvEpreview.addFooterView(LayoutInflater.from(AllEboradPreviewActivity.this).inflate(R.layout.test_footer,null));
adapter.setListener(new AllEBoardPreviewAdapter.onItemClickListener() {
@Override
public void onItemClick(int position) {
adapter.removeItem(position);
}
});
package eboardmodule.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import com.orhanobut.logger.Logger;
import com.wyt.hcy.aiyixue_teacher.R;
import org.w3c.dom.Text;
import adapter.CommonViewHolder;
/**
* Created by hcy on 2017/4/14 0014.
* func:
*/
public class AllEBoardPreviewAdapter extends RecyclerView.Adapter {
private List dataList;
public AllEBoardPreviewAdapter(List dataList) {
//dataList=new ArrayList();
this.dataList = dataList;
}
private onItemClickListener listener;
public void setListener(onItemClickListener listener) {
this.listener = listener;
}
public void setDataSource(List list) {
this.dataList = list;
notifyDataSetChanged();
}
public void removeItem(int pos){
dataList.remove(pos);
notifyDataSetChanged();
}
@Override
public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.test1, parent,false);
/* return new RecyclerView.ViewHolder(itemView) {
};*/
return new CommonViewHolder(itemView);
}
@Override
public void onBindViewHolder(CommonViewHolder holder, final int position) {
//=holder.getView(R.id.tv);
// TextView tv = (TextView) holder.itemView.findViewById(R.id.tv);
/* MyViewHolder myViewHolder= (MyViewHolder) holder;
Logger.d("PPPP::"+position);
myViewHolder.tv.setText(dataList.get(position));*/
TextView tv=holder.getView(R.id.tv);
tv.setText(dataList.get(position));
LinearLayout item= holder.getView(R.id.item_test);
item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener!=null){
listener.onItemClick(position);
}
}
});
}
@Override
public int getItemCount() {
return dataList.size();
}
private class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tv;
public MyViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}
public interface onItemClickListener{
void onItemClick(int position);
}
}
package adapter;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* Created by hcy on 2016/11/14.
* func:Listview 通用的ViewHolder
*/
public class CommonViewHolder extends RecyclerView.ViewHolder {
private final SparseArray mViews;
private View mConvertView;
private int selectItem = -1;
public void setSelectItem(int selectItem) {
this.selectItem = selectItem;
}
public CommonViewHolder(View itemView) {
super(itemView);
mConvertView = itemView;
this.mViews = new SparseArray();
}
/**
* 通过控件的Id获取对于的控件,如果没有则加入views
*
* @param viewId
* @return
*/
public T findViewById(int viewId) {
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}
//设置文本
public void setText(int textViewID, String text, int visibility) {
TextView textView = findViewById(textViewID);
textView.setVisibility(visibility);
textView.setText(text);
}
public void setTextBackground(int textViewID, int background) {
TextView textView = findViewById(textViewID);
textView.setBackgroundResource(background);
}
public void setImage(int imageviewId, int res) {
ImageView imageView = findViewById(imageviewId);
imageView.setImageResource(res);
}
public T getView(int viewid) {
return findViewById(viewid);
}
}