android 积累一些RecycylerView的常见用法

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;
    }

2.实现过滤器

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");
            }*/
        }
    }

3.设置过滤器

   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;
        }
    }

2.根据不同的分类加载不同的View

    @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);
        }
        
    }


RecyclerView添加头部与尾部


仿造ListView添加addHeaderView与addFooterView

原理:在ListView中添加头部或者尾部,是在原有的基础的adpter上,添加了一个装饰的adapter:
HeaderViewListAdapter
也就是在原有的基础上,将数据分为三部分:头部,中部,底部,用getViewType来区别数据

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));

扩展:有时候需要添加删除数据,上面那个就不能使用了:因为我们只通知了数据源的那个adapter刷新,那个包装的那个adpter却没有通知跟新

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);
            }
        });

我的数据源adapter:
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);
    }


}

之前写的万能适配器里的ViewHolder

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);

    }

}







你可能感兴趣的:(Android)