zoukankan      html  css  js  c++  java
  • RecyclerView的那点事儿

    RecyclerView

    控件简单介绍

    • ListView的升级版
    • LinearLayoutManager
    • GridLayoutManager
    • StaggeredGridLayoutManager
    • 定制Item动画,指定Item之间的分隔线

    RecyclerView相关的重要类

    • Adapter
    • ViewHolder
    • LayoutManager
    • ItemDecoration
    • ItemAnimator

    加入RecyclerView控件依赖包

    Android Studio开发工具,在本项目的build.gradle文件里加入

      compile 'com.android.support:recyclerview-v7:23.1.1'

    假设是eclipse的话,下载jar包。放到lib下。一般都会自己主动的build path,检查下就可以。

    怎样下载jar ?
    在SDK Manager中下载Support Library
    这里写图片描写叙述

    sdkextrasandroidsupportv7 ecyclerviewlibs

    这里写图片描写叙述

    为Recycler准备数据

    package demo.turing.com.materialdesignwidget.recyclerView;
    
    import java.util.ArrayList;
    
    import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
    
    /**
     * MyApp
     *
     * @author Mr.Yang on 2016-03-30  20:21.
     * @version 1.0
     * @desc
     */
    public class SimulatorData {
    
    
        public static ArrayList<SampleModel> getSampleModelData(int size) {
    
            ArrayList<SampleModel> sampleData = new ArrayList<SampleModel>(size);
    
            for (int i = 0; i < size; i++) {
                sampleData.add(new SampleModel("新的列表项< " + i + " >"));
            }
    
            return sampleData;
        }
    
    }
    
    package demo.turing.com.materialdesignwidget.recyclerView.model;
    
    /**
     * MyApp
     *
     * @author Mr.Yang on 2016-03-30  20:23.
     * @version 1.0
     * 相应Item中药显示的数据项
     */
    public class SampleModel {
    
    
    
        private String text;
    
    
        public SampleModel(String text) {
            this.text = text;
        }
    
    
        public String getText() {
            return text;
        }
    
        public void setText(String text) {
            this.text = text;
        }
    }
    

    绘制列表项之间的分隔线

    这里写图片描写叙述

    package demo.turing.com.materialdesignwidget.recyclerView;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    
    /**
     * MyApp
     *
     * @author Mr.Yang on 2016-03-30  20:37.
     * @version 1.0
     *          分隔条
     *
     *
     *   DividerItemDecoration  https://gist.github.com/alexfu/0f464fc3742f134ccd1e
     */
    public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    
        // 默认分隔条Drawable资源的ID,使用系统自带的
        private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    
        public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    
        public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
    
    
        private Drawable mDivider;
    
        private int mOrientation;
    
        public DividerItemDecoration(Context context, int orientation) {
            // 使用TypedArray装载定义的ATTRS
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            // 获取系统提供的分隔条Drawable对象
            mDivider = a.getDrawable(0);
            // 回收TypedArray所占用的空间
            a.recycle();
            setOrientation(orientation);
        }
    
    
        /**
         * 设置item的显示 水平 or 垂直
         *
         * @param orientation
         */
        public void setOrientation(int orientation) {
            if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
                throw new IllegalArgumentException("invalid orientation");
            }
            mOrientation = orientation;
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent) {
            if (mOrientation == VERTICAL_LIST) {
                drawVertical(c, parent);
            } else {
                drawHorizontal(c, parent);
            }
        }
    
        public void drawVertical(Canvas c, RecyclerView parent) {
            final int left = parent.getPaddingLeft();
            final int right = parent.getWidth() - parent.getPaddingRight();
    
            final int childCount = parent.getChildCount();
    
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                RecyclerView v = new android.support.v7.widget.RecyclerView(
                        parent.getContext());
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    
        public void drawHorizontal(Canvas c, RecyclerView parent) {
            final int top = parent.getPaddingTop();
            final int bottom = parent.getHeight() - parent.getPaddingBottom();
    
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    
        @Override
        public void getItemOffsets(Rect outRect, int itemPosition,
                                   RecyclerView parent) {
            if (mOrientation == VERTICAL_LIST) {
                outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
            } else {
                outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
            }
        }
    
    }
    
    

    实现Adapter

    package demo.turing.com.materialdesignwidget.recyclerView.adapter;
    
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.Random;
    
    import demo.turing.com.materialdesignwidget.R;
    import demo.turing.com.materialdesignwidget.recyclerView.SimulatorData;
    import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
    
    /**
     * MyApp
     *
     * @author Mr.Yang on 2016-03-30  21:03.
     * @version 1.0
     * @desc
     */
    public class SampleRecyclerAdapter extends RecyclerView.Adapter<SampleRecyclerAdapter.ViewHolder> {
    
        // 模拟数据
        private  ArrayList<SampleModel> sampleData = SimulatorData.getSampleModelData(20);
    
        /**
         * 用于创建控件
         *
         * @param parent
         * @param viewType
         * @return
         */
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            // 获得列表项控件(LinearLayer对象)
    
            // list_basic_item.xml布局文件里仅仅包括一个<LinearLayer>标签,
            // 在该标签中包括了一个<TextView>标签, item是LinearLayout对象
            View item = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.list_basic_item, parent, false);
    
            ViewHolder viewHolder = new ViewHolder(item);
    
            return viewHolder;
        }
    
        /**
         * 为控件设置数据
         *
         * @param holder
         * @param position
         */
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
    
            //  获取当前item中显示的数据
            final SampleModel rowData = sampleData.get(position);
    
            //  设置要显示的数据
            holder.textViewSample.setText(rowData.getText());
            // 设置tag
            holder.itemView.setTag(rowData);
    
        }
    
    
        @Override
        public int getItemCount() {
            return sampleData.size();
        }
    
    
        /**
         * 删除指定的Item
         *
         * @param position
         */
        public void removeData(int position) {
            sampleData.remove(position);
            //  通知RecyclerView控件某个Item已经被删除
            notifyItemRemoved(position);
    
        }
    
    
        /**
         * 在指定位置加入一个新的Item
         *
         * @param positionToAdd
         */
        public void addItem(int positionToAdd) {
            sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));
            //  通知RecyclerView控件插入了某个Item
            notifyItemInserted(positionToAdd);
        }
    
    
        /**
         * 相应Item中的控件
         */
        public static class ViewHolder extends RecyclerView.ViewHolder {
    
            private final TextView textViewSample;
    
            public ViewHolder(View itemView) {
                super(itemView);
                textViewSample = (TextView) itemView
                        .findViewById(R.id.textViewSample);
            }
        }
    
    
    }
    

    完毕使用RecyclerView控件的最后工作

    package demo.turing.com.materialdesignwidget.recyclerView;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    
    import demo.turing.com.materialdesignwidget.R;
    import demo.turing.com.materialdesignwidget.recyclerView.adapter.SampleRecyclerAdapter;
    
    public class RecyclerViewAct extends AppCompatActivity {
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_recycler_view);
    
            // 获取RecyclerView对象
            RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
    
            //  创建线性布局管理器(默认是垂直方向)
            LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
    
    
            //  为RecyclerView指定布局管理对象
            recyclerView.setLayoutManager(layoutManager);
    
            //  创建列表项分隔线对象
            RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST);
    
            //  为RecyclerView控件指定分隔线对象
            recyclerView.addItemDecoration(itemDecoration);
    
            SampleRecyclerAdapter sampleRecyclerAdapter = new SampleRecyclerAdapter();
            recyclerView.setAdapter(sampleRecyclerAdapter);
    
    
        }
    
    
    }
    
    

    效果图

    这里写图片描写叙述

    定制个性化分隔条

    drawabledivider_custom.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    
        <size android:height="4dp"></size>
        <!--渐变色-->
        <gradient
            android:centerColor="#ff0000ff"
            android:endColor="#ffff0000"
            android:startColor="#ffff0000"
            android:type="linear"></gradient>
    
    
    </shape>

    主题中设置

      <item name="android:listDivider">@drawable/divider_custom</item>

    瀑布流

    StaggeredGridLayuoutAct.java

    package demo.turing.com.materialdesignwidget.recyclerView;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.StaggeredGridLayoutManager;
    
    import java.util.List;
    
    import demo.turing.com.materialdesignwidget.R;
    import demo.turing.com.materialdesignwidget.recyclerView.adapter.StaggeredGridLayoutAdapter;
    import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
    
    
    /**
     * 不採用分隔线, 在Item的布局中 採用layout_margin的方式
     *
     * 主要是动态设置View的高度 adapter类中的 onBindViewHolder
     */
    
    public class StaggeredGridLayuoutAct extends AppCompatActivity {
    
        private RecyclerView recyclerView ;
    
        // 模拟数据
        private List<SampleModel> sampleData = SimulatorData.getSampleModelData(20);
    
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_staggered_grid_layuout);
    
            // 查找组件
            recyclerView = (RecyclerView) findViewById(R.id.id_rv_staggered);
    
            // 创建布局管理器  -3列,垂直
            StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
            // 设置布局
            recyclerView.setLayoutManager(manager);
    
            // Adapter
            StaggeredGridLayoutAdapter adapter = new StaggeredGridLayoutAdapter(this,sampleData);
            recyclerView.setAdapter(adapter);
    
    
    
    
        }
    }
    

    activity_staggered_grid_layuout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="demo.turing.com.materialdesignwidget.recyclerView.StaggeredGridLayuoutAct">
    
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/id_rv_staggered"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
    
    </RelativeLayout>
    

    StaggeredGridLayoutAdapter.java

    package demo.turing.com.materialdesignwidget.recyclerView.adapter;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import demo.turing.com.materialdesignwidget.R;
    import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
    
    /**
     * MyApp
     *
     * @author Mr.Yang on 2016-03-31  20:19.
     * @version 1.0
     * @desc
     */
    public class StaggeredGridLayoutAdapter extends RecyclerView.Adapter<StaggeredGridLayoutAdapter.ViewHolder> {
    
    
        private Context context;
        private List<SampleModel> datas;
        private LayoutInflater inflater;
        // 随机高度的结合
        private List<Integer> mHeights;
    
        /**
         * 构造函数
         *
         * @param context
         * @param datas
         */
        public StaggeredGridLayoutAdapter(Context context, List<SampleModel> datas) {
            this.context = context;
            this.datas = datas;
            this.inflater = LayoutInflater.from(context);
    
    
            // 初始化随机高度的集合
            mHeights = new ArrayList<>();
            for (int i = 0; i < datas.size(); i++) {
                mHeights.add((int)(100 + Math.random() * 300));
            }
        }
    
        @Override
        public StaggeredGridLayoutAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            // 动态载入Item的布局文件
            View view = inflater.inflate(R.layout.list_basic_item, parent, false);
            // 实例化ViewHolder
            ViewHolder viewHolder = new ViewHolder(view);
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(StaggeredGridLayoutAdapter.ViewHolder holder, int position) {
    
    
            // 获取当前Item中的显示的数据
            SampleModel sampleModel = datas.get(position);
    
            //设置控件的随机高度
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
            lp.height = mHeights.get(position);
            holder.itemView.setLayoutParams(lp);
    
    
            // 设置组件的值
            holder.textView.setText(sampleModel.getText());
            // 设置tag
            holder.itemView.setTag(sampleModel);
    
        }
    
    
        @Override
        public int getItemCount() {
            return datas.size();
        }
    
        /**
         * ViewHoder
         */
        class ViewHolder extends RecyclerView.ViewHolder {
    
            TextView textView;
    
            public ViewHolder(View itemView) {
                super(itemView);
                textView = (TextView) itemView
                        .findViewById(R.id.textViewSample);
            }
        }
    }
    

    list_basic_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="3dp"
        android:background="#6495ED"
        android:gravity="center"
        android:orientation="horizontal">
    
        <TextView
            android:id="@+id/textViewSample"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="演示"/>
    
    </RelativeLayout>

    效果图

    这里写图片描写叙述

    动画效果

     // 默认动画效果
     recyclerView.setItemAnimator(new DefaultItemAnimator());

    notifyItemRemoved(position)

     /**
         * 删除指定的Item
         *
         * @param position
         */
        public void removeData(int position) {
            sampleData.remove(position);
            //  通知RecyclerView控件某个Item已经被删除
            notifyItemRemoved(position);
    
        }

    notifyItemInserted(positionToAdd)

        /**
         * 在指定位置加入一个新的Item
         *
         * @param positionToAdd
         */
        public void addItem(int positionToAdd) {
            sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));
            //  通知RecyclerView控件插入了某个Item
            notifyItemInserted(positionToAdd);
        }

    为RecyclerView加入item的点击事件

    方法一:利用回调的方式实现(不太完好,仍可实现)

    实现过程例如以下:
    在adapter类中,定义接口,接口中定义两个方法分别相应click和longClick,定义完接口。加入接口和设置Adapter接口的方法:

      /**
         * 接口 ,提供两个方法
         */
        public interface OnRecyclerViewItemClickListener{
            // 单击事件
            void onItemClick(View view ,int position);
            // 长按触发的事件
            void onItemLongClick(View view ,int position);
        }
        // 定义OnRecyclerViewItemClickListener对象
        public OnRecyclerViewItemClickListener  mOnRecyclerViewItemClickListener ;
    
        // 暴漏给外部的set方法。持有OnRecyclerViewItemClickListener对象
        public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener){
            this.mOnRecyclerViewItemClickListener = listener ;
        }
    

    在onBindViewHolder方法中

     // 点击事件
            if(mOnRecyclerViewItemClickListener != null){
                // click
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mOnRecyclerViewItemClickListener.onItemClick(holder.itemView,position);
                    }
                });
                // longClick
                holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        mOnRecyclerViewItemClickListener.onItemLongClick(holder.itemView,position);
                        return false;
                    }
                });
    
            }

    做完这些事情,我们就能够在Activity或其它地方为RecyclerView加入项目点击事件了,

    // 设置监事件
            sampleRecyclerAdapter.setOnRecyclerViewItemClickListener(new SampleRecyclerAdapter.OnRecyclerViewItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    Toast.makeText(RecyclerViewAct.this,"Click" + position ,Toast.LENGTH_SHORT).show();
                }
    
                @Override
                public void onItemLongClick(View view, int position) {
                    Toast.makeText(RecyclerViewAct.this,"LongClick" + position ,Toast.LENGTH_SHORT).show();
    
                }
            });

    完整代码例如以下:

    RecyclerViewAct

    package demo.turing.com.materialdesignwidget.recyclerView;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.DefaultItemAnimator;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.Toast;
    
    import demo.turing.com.materialdesignwidget.R;
    import demo.turing.com.materialdesignwidget.recyclerView.adapter.SampleRecyclerAdapter;
    
    public class RecyclerViewAct extends AppCompatActivity {
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_recycler_view);
    
            // 获取RecyclerView对象
            RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
    
            //  创建线性布局管理器(默认是垂直方向)
            LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
    
    
            //  为RecyclerView指定布局管理对象
            recyclerView.setLayoutManager(layoutManager);
    
            //  创建列表项分隔线对象
            RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST);
    
            //  为RecyclerView控件指定分隔线对象
            recyclerView.addItemDecoration(itemDecoration);
    
    
    
            // 默认动画效果
            recyclerView.setItemAnimator(new DefaultItemAnimator());
    
    
            SampleRecyclerAdapter sampleRecyclerAdapter = new SampleRecyclerAdapter();
            recyclerView.setAdapter(sampleRecyclerAdapter);
    
    
    
            // 设置监事件
            sampleRecyclerAdapter.setOnRecyclerViewItemClickListener(new SampleRecyclerAdapter.OnRecyclerViewItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    Toast.makeText(RecyclerViewAct.this,"Click" + position ,Toast.LENGTH_SHORT).show();
                }
    
                @Override
                public void onItemLongClick(View view, int position) {
                    Toast.makeText(RecyclerViewAct.this,"LongClick" + position ,Toast.LENGTH_SHORT).show();
    
                }
            });
        }
    
    
    }
    

    SampleRecyclerAdapter

    package demo.turing.com.materialdesignwidget.recyclerView.adapter;
    
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.Random;
    
    import demo.turing.com.materialdesignwidget.R;
    import demo.turing.com.materialdesignwidget.recyclerView.SimulatorData;
    import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
    
    /**
     * MyApp
     *
     * @author Mr.Yang on 2016-03-30  21:03.
     * @version 1.0
     * @desc
     *
     *
     * RecyclerView  点击事件 请看http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1118/2004.html
    */
    public class SampleRecyclerAdapter extends RecyclerView.Adapter<SampleRecyclerAdapter.ViewHolder> {
    
        // 模拟数据
        private  ArrayList<SampleModel> sampleData = SimulatorData.getSampleModelData(20);
    
    
        /**
         * 接口 ,提供两个方法
         */
        public interface OnRecyclerViewItemClickListener{
            // 单击事件
            void onItemClick(View view ,int position);
            // 长按触发的事件
            void onItemLongClick(View view ,int position);
        }
        // 定义OnRecyclerViewItemClickListener对象
        public OnRecyclerViewItemClickListener  mOnRecyclerViewItemClickListener ;
    
        // 暴漏给外部的set方法。持有OnRecyclerViewItemClickListener对象
        public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener){
            this.mOnRecyclerViewItemClickListener = listener ;
        }
    
    
        /**
         * 用于创建控件
         *
         * @param parent
         * @param viewType
         * @return
         */
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            // 获得列表项控件(LinearLayer对象)
    
            // list_basic_item.xml布局文件里仅仅包括一个<LinearLayer>标签,
            // 在该标签中包括了一个<TextView>标签, item是LinearLayout对象
            View item = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.list_basic_item, parent, false);
    
            ViewHolder viewHolder = new ViewHolder(item);
    
            return viewHolder;
        }
    
        /**
         * 为控件设置数据
         *
         * @param holder
         * @param position
         */
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
    
            //  获取当前item中显示的数据
            final SampleModel rowData = sampleData.get(position);
    
            //  设置要显示的数据
            holder.textViewSample.setText(rowData.getText());
            // 设置tag
            holder.itemView.setTag(rowData);
    
             // 点击事件
     if(mOnRecyclerViewItemClickListener != null){
                // click
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // 通过getLayoutPosition,防止position错位
                        int layoutPosition = holder.getLayoutPosition();
                        mOnRecyclerViewItemClickListener.onItemClick(holder.itemView,layoutPosition);
                    }
                });
                // longClick
                holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        int layoutPosition = holder.getLayoutPosition();
                        mOnRecyclerViewItemClickListener.onItemLongClick(holder.itemView,layoutPosition);
                        return false;
                    }
                });
            }
        }
    
    
        @Override
        public int getItemCount() {
            return sampleData.size();
        }
    
    
        /**
         * 删除指定的Item
         *
         * @param position
         */
        public void removeData(int position) {
            sampleData.remove(position);
            //  通知RecyclerView控件某个Item已经被删除
            notifyItemRemoved(position);
    
        }
    
    
        /**
         * 在指定位置加入一个新的Item
         *
         * @param positionToAdd
         */
        public void addItem(int positionToAdd) {
            sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));
            //  通知RecyclerView控件插入了某个Item
            notifyItemInserted(positionToAdd);
        }
    
    
        /**
         * 相应Item中的控件
         */
        public static class ViewHolder extends RecyclerView.ViewHolder {
    
            private final TextView textViewSample;
    
            public ViewHolder(View itemView) {
                super(itemView);
                textViewSample = (TextView) itemView
                        .findViewById(R.id.textViewSample);
            }
        }
    
    
    }
    

    方法二:使用观察者模式实现

    原理:
    为RecyclerView的每一个子item设置setOnClickListener。然后在onClick中再调用一次对外封装的接口。将这个事件传递给外面的调用者。而“为RecyclerView的每一个子item设置setOnClickListener”在Adapter中设置。事实上直接在onClick中也能全然处理item的点击事件,可是这样会破坏代码的逻辑。

    步骤
    在自己定义的adapter(记得implements View.OnClickListener,以下有个onClick方法)中定义例如以下接口,模拟ListView的OnItemClickListener:

     //define interface
     public static interface OnRecyclerViewItemClickListener {
            void onItemClick(View view , String data);
        }

    声明一个这个接口的变量:

      private OnRecyclerViewItemClickListener mOnItemClickListener = null;

    在onCreateViewHolder()中为每一个item加入点击事件:

     @Override
        public ViewHolder onCreateViewHolder(ViewGroup viewGroup,  int viewType) {
            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
            ViewHolder vh = new ViewHolder(view);
            //将创建的View注冊点击事件
            view.setOnClickListener(this);
            return vh;
        }

    将点击事件转移给外面的调用者:

     @Override
        public void onClick(View v) {
            if (mOnItemClickListener != null) {
                //注意这里使用getTag方法获取数据
                mOnItemClickListener.onItemClick(v,(String)v.getTag());
            }
        }

    意上面调用接口的onItemClick()中的v.getTag()方法,这须要在onBindViewHolder()方法中设置和item相关的数据

    @Override
        public void onBindViewHolder(ViewHolder viewHolder,  int position) {
            viewHolder.mTextView.setText(datas[position]);
            //将数据保存在itemView的Tag中,以便点击时进行获取
            viewHolder.itemView.setTag(datas[position]);
        }

    最后暴露给外面的调用者,定义一个设置Listener的方法():

     public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
            this.mOnItemClickListener = listener;
        }

    以上全部步骤都发生在自己定义的adapter中,典型的观察者模式,有点绕的地方在于,这里涉及到两个观察者模式的使用,view的setOnClickListener本来就是观察者模式,我们将这个观察者模式的事件监听传递给了我们自己的观察者模式。

    在Activity中使用

    mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
            //创建默认的线性LayoutManager
            mLayoutManager = new LinearLayoutManager(this);
            mRecyclerView.setLayoutManager(mLayoutManager);
            //假设能够确定每一个item的高度是固定的,设置这个选项能够提高性能
            mRecyclerView.setHasFixedSize(true);
            //创建并设置Adapter
            mAdapter = new MyAdapter(data);
            mRecyclerView.setAdapter(mAdapter);
            mAdapter.setOnItemClickListener(new OnRecyclerViewItemClickListener(){
                @Override    
                public void onItemClick(View view , String data){
                    Toast.makeText(MainActivity.this, data, 600).show();
                }
            });

    ~

    RecyclerView加入Header

    。。。。。。

  • 相关阅读:
    协议(五)-从电报机到智能手机
    协议(四)-通信发展史
    NDK历史版本
    android onKeyDown
    设计模式
    Android获取系统时间的多种方法
    USB 3.0规范中译本 第5章 机械结构
    ES6新特性
    08_SQLyog图形化工具介绍
    07_聚合函数,分组查询&limit关键字
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7233273.html
Copyright © 2011-2022 走看看