Android学习笔记--RecycleView用法

1.什么是RecyclerView

RecyclerView是Android 5.0 materials design中的组件之一。通过名字我们就能看出一点端倪,没错,它主要的特点就是复用。我们知道,Listview中的Adapter中可以实现ViewHolder的复用。RecyclerView提供了一个耦合度更低的方式来复用ViewHolder,并且可以轻松的实现ListView、GridView以及瀑布流的效果。

2.RecycleView怎么引用

  Android Studio
dependencies {
    compile 'com.android.support:recyclerview-v7:21.0.0'
}
先介绍三个东西:

Adapter:使用RecyclerView之前,你需要一个继承自RecyclerView.Adapter的适配器,作用是将数据与每一个item的界面进行绑定

ViewHolder:用来保存视图引用的类.(这个与ListView可选不同,必须使用)

LayoutManager:用来确定每一个item如何进行排列摆放,何时展示和隐藏。回收或重用一个View的时候,LayoutManager会向适配器请求新的数据来替换旧的数据,这种机制避免了创建过多的View和频繁的调用findViewById方法(与ListView原理类似

3.基本用法

mRecyclerView = findView(R.id.id_recyclerview);
mRecyclerView.setLayoutManager(layout);//设置布局管理器
mRecyclerView.setAdapter(adapter)//设置adapter
// 设置item动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());//系统提供的默认动画


最简单的用法(效果ListView一样)

主布局:



    

Item的布局:



    
MainActiviyu:

import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity
{

    private RecyclerView mRecyclerView;
    private List mDatas;
    private HomeAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_recyclerview);

        initData();
        mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mAdapter = new HomeAdapter());

    }

    protected void initData()
    {
        mDatas = new ArrayList();
        for (int i = 0; i < 30; i++)
        {
            mDatas.add("" +  i);
        }
    }

    class HomeAdapter extends RecyclerView.Adapter
    {

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
                    HomeActivity.this).inflate(R.layout.item_home, parent,
                    false));
            return holder;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position)
        {
            holder.tv.setText(mDatas.get(position));
        }

        @Override
        public int getItemCount()
        {
            return mDatas.size();
        }

        class MyViewHolder extends ViewHolder
        {

            TextView tv;

            public MyViewHolder(View view)
            {
                super(view);
                tv = (TextView) view.findViewById(R.id.id_num);
            }
        }
    }

}

4.LayoutManager:

横向布局
如果想要一个横向的List只要设置LinearLayoutManager如下就行,注意要声明mLayoutManager的类型是LinearLayoutManager而不是父类LayoutManager:

mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
Grid布局
如果想要一个Grid布局的列表,只要声明LayoutManager为GridLayoutManager即可:
mLayoutManager = new GridLayoutManager(context,columNum);
mRecyclerView.setLayoutManager(mLayoutManager);
注意,在Grid布局中也可以设置列表的Orientation属性,来实现横向和纵向的Grid布局。

瀑布流布局
瀑布流就使用StaggeredGridLayoutManager吧,具体方法与上面类似,就不介绍了。

你还可以增加添加和删除数据的方法:

public void addData(int position) {
        mDatas.add(position, "add add add");
        notifyItemInserted(position);
    }

    public void removeData(int position) {
            mDatas.remove(position);
        notifyItemRemoved(position);
    }


5.点击事件

RecyclerView的api发现虽然没有提供onItemClickListener但是提供了addOnItemTouchListener方法这里我有两种实现点击的方法。第一种是通过mRecyclerView.addOnItemTouchListener去监听然后去判断手势,第二种是通过adapter中自己去提供回调。

第一种:

1.定义一个类OnRecyclerItemClickListener实现OnItemTouchListener,我们需要实现其3个方法:

@Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    }

其中第三个方法是处理触摸事件冲突的,跟我们没关系不用管它,前两个方法是不是很熟悉呢,这不就是View的事件分发机制里面的事件拦截和事件处理的两个方法吗,参数里为我们提供了触摸事件的数据MotionEvent,我们要做的就是去解析坐标点和触摸规律来识别触摸手势,然后获取触摸的是哪一个item,再执行我们的回调。

定义一个ItemTouchHelperGestureListener 继承自SimpleOnGestureListener ,实现onSingleTapUp方法:

private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
      @Override
      public boolean onSingleTapUp(MotionEvent e) {
      }
}
获取到了RecyclerView的点击事件和触摸事件数据MotionEvent ,那么我们怎么知道点击的是哪一个item呢?RecyclerView已经为我们提供了这样的方法:findChildViewUnder(),我们可以通过这个方法获得点击的item,同时我们调用RecyclerView的另一个方法getChildViewHolder(),可以获得该item的ViewHolder,最后再回调我们定义的虚方法onItemClick()就ok了,这样我们就可以在外部实现该方法来获得item的点击事件了:

@Override
public boolean onSingleTapUp(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
     if (child!=null) {
         RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
         onItemClick(vh);
     }
     return true;
}
完整代码如下:

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private List mData;
    private myAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        mRecyclerView= (RecyclerView) findViewById(R.id.recycleView);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setAdapter(mAdapter=new myAdapter());
        mRecyclerView.addOnItemTouchListener(new onRecycleItemClickListener(mRecyclerView) {
            @Override
            public void onItemClick(RecyclerView.ViewHolder vh) {
                //具体点击事件
                Toast.makeText(MainActivity.this, "hah",Toast.LENGTH_SHORT).show();
            }
        });

    }
    private void initData(){
        mData=new ArrayList();
        for (int i = 'A'; i < 'Z'; i++) {
            mData.add(""+(char)i);
        }
    }
    public abstract class onRecycleItemClickListener implements RecyclerView.OnItemTouchListener{
        private GestureDetector mGestureDetector;
        private RecyclerView recycleView;

        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            mGestureDetector.onTouchEvent(e);
            return false;
        }
        //处理触摸冲突的方法
        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        }

        @Override
        public void onTouchEvent(RecyclerView rv, MotionEvent e) {
            mGestureDetector.onTouchEvent(e);
        }

        public onRecycleItemClickListener(RecyclerView recycleView) {
            this.recycleView = recycleView;
            mGestureDetector=new GestureDetector(MainActivity.this,new ItemTouchHelperGestureListener());

        }
        private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener{
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                View view=recycleView.findChildViewUnder(e.getX(),e.getY());
                if (view!=null){
                     RecyclerView.ViewHolder holder=recycleView.getChildViewHolder(view);
                    onItemClick(holder);
                }
                return true;
            }
            //长点击事件,本例不需要不处理
            //@Override
            //public void onLongPress(MotionEvent e) {
            //    View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            //    if (child!=null) {
            //        RecyclerView.myHolder vh = recyclerView.getChildViewHolder(child);
            //        onItemLongClick(vh);
            //    }
            //}

        }
        public abstract void onItemClick(RecyclerView.ViewHolder vh);
        //public abstract void onItemLongClick(RecyclerView.myHolder vh);
    }
   public class myAdapter extends RecyclerView.Adapter{
        @Override
        public myHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            myHolder holder=new myHolder(LayoutInflater.from(MainActivity.this).inflate(R.layout.item,parent,
                    false));

            return holder;
        }

        @Override
        public void onBindViewHolder(myHolder holder, int position) {
            holder.item_tv.setText(mData.get(position));
        }
       //添加item
       public void addItem(int position){
           mData.add(position,"insert one");
           notifyItemInserted(position);
       }
       //删除item
       public void removeData(int position){
           mData.remove(position);
           notifyItemRemoved(position);
       }

       @Override
        public int getItemCount() {
            return mData.size();
        }
        public class myHolder extends RecyclerView.ViewHolder{

             TextView item_tv;
            public myHolder(View itemView) {
                super(itemView);
                item_tv= (TextView) itemView.findViewById(R.id.item_tv);
            }
        }
    }
}
第二种方法:

这个代码比较简单,先在RecyclerView.Adapter中添加回调接口:

public interface OnItemClickLitener
    {
        void onItemClick(View view, int position);
        void onItemLongClick(View view , int position);
    }

    private OnItemClickLitener mOnItemClickLitener;

    public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
    {
        this.mOnItemClickLitener = mOnItemClickLitener;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position)
    {
        holder.tv.setText(mDatas.get(position));

        // 如果设置了回调,则设置点击事件
        if (mOnItemClickLitener != null)
        {
            holder.itemView.setOnClickListener(new OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickLitener.onItemClick(holder.itemView, pos);
                }
            });

            holder.itemView.setOnLongClickListener(new OnLongClickListener()
            {
                @Override
                public boolean onLongClick(View v)
                {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickLitener.onItemLongClick(holder.itemView, pos);
                    return false;
                }
            });
        }
    }
然后再Activity中设置监听:

  mAdapter.setOnItemClickLitener(new OnItemClickLitener()
        {

            @Override
            public void onItemClick(View view, int position)
            {
                Toast.makeText(HomeActivity.this, position + " click",
                        Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onItemLongClick(View view, int position)
            {
                Toast.makeText(HomeActivity.this, position + " long click",
                        Toast.LENGTH_SHORT).show();
                        mAdapter.removeData(position);
            }
        });
就OK了。


你可能感兴趣的:(Android,android,RecycleView)