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

    。。。。。。

  • 相关阅读:
    UVa 12174 (滑动窗口) Shuffle
    UVa 1607 (二分) Gates
    CodeForces ZeptoLab Code Rush 2015
    HDU 1525 (博弈) Euclid's Game
    HDU 2147 (博弈) kiki's game
    UVa 11093 Just Finish it up
    UVa 10954 (Huffman 优先队列) Add All
    CodeForces Round #298 Div.2
    UVa 12627 (递归 计数 找规律) Erratic Expansion
    UVa 714 (二分) Copying Books
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7233273.html
Copyright © 2011-2022 走看看