赞
踩
- dependencies {
- compile 'com.android.support:recyclerview-v7:21.0.0'
- }
先介绍三个东西:
Adapter:使用RecyclerView之前,你需要一个继承自RecyclerView.Adapter的适配器,作用是将数据与每一个item的界面进行绑定
ViewHolder:用来保存视图引用的类.(这个与ListView可选不同,必须使用)
LayoutManager:用来确定每一个item如何进行排列摆放,何时展示和隐藏。回收或重用一个View的时候,LayoutManager会向适配器请求新的数据来替换旧的数据,这种机制避免了创建过多的View和频繁的调用findViewById方法(与ListView原理类似)
- mRecyclerView = findView(R.id.id_recyclerview);
- mRecyclerView.setLayoutManager(layout);//设置布局管理器
- mRecyclerView.setAdapter(adapter)//设置adapter
- // 设置item动画
- mRecyclerView.setItemAnimator(new DefaultItemAnimator());//系统提供的默认动画
最简单的用法(效果ListView一样)
主布局:
- <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.support.v7.widget.RecyclerView
- android:id="@+id/id_recyclerview"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- </RelativeLayout>
Item的布局:
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:background="#fff"
- android:layout_height="wrap_content" >
-
- <TextView
- android:id="@+id/id_tv_item"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:gravity="center"
- android:text="" />
- </LinearLayout>
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<String> 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<String>();
- for (int i = 0; i < 30; i++)
- {
- mDatas.add("" + i);
- }
- }
-
- class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>
- {
-
- @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);
- }
- }
- }
-
- }
横向布局
如果想要一个横向的List只要设置LinearLayoutManager如下就行,注意要声明mLayoutManager的类型是LinearLayoutManager而不是父类LayoutManager:
mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
Grid布局
- mLayoutManager = new GridLayoutManager(context,columNum);
- mRecyclerView.setLayoutManager(mLayoutManager);
注意,在Grid布局中也可以设置列表的Orientation属性,来实现横向和纵向的Grid布局。
你还可以增加添加和删除数据的方法:
- public void addData(int position) {
- mDatas.add(position, "add add add");
- notifyItemInserted(position);
- }
-
- public void removeData(int position) {
- mDatas.remove(position);
- notifyItemRemoved(position);
- }
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) {
- }
定义一个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<String> 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<String>();
- 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<myAdapter.myHolder>{
- @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了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。