Android学习笔记--RecycleView用法
来源:互联网 发布:节奏大师网络拦截 编辑:程序博客网 时间:2024/05/22 03:48
1.什么是RecyclerView
RecyclerView是Android 5.0 materials design中的组件之一。通过名字我们就能看出一点端倪,没错,它主要的特点就是复用。我们知道,Listview中的Adapter中可以实现ViewHolder的复用。RecyclerView提供了一个耦合度更低的方式来复用ViewHolder,并且可以轻松的实现ListView、GridView以及瀑布流的效果。2.RecycleView怎么引用
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一样)
主布局:
<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); } } }}
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的点击事件了:
@Overridepublic 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了。
- Android学习笔记--RecycleView用法
- Android Recycleview的用法
- android studio- RecycleView学习实践
- RecyCleView用法
- 【Android学习笔记】RecycleView 绑定了Adapter的item明明设置了match_parent却不起作用
- 【Android学习笔记】LinearLayout嵌套RecycleView后无法点击,onClick失效的问题
- 【Android学习笔记】LinearLayout嵌套RecycleView后无法点击,onClick失效的问题
- 【Android学习笔记】RecycleView 绑定了Adapter的item明明设置了match_parent却不起作用
- 学习recycleview
- RecycleView学习
- android recycleView
- Android RecycleView
- Android-RecycleView
- Android之---RecycleView简单介绍(各种用法的简介)
- RecycleView用法总结
- RecycleView的基本用法
- RecycleView的用法
- RecycleView的基本用法
- 【Servlet开发】servlet的请求与响应(二)
- mybatis注解详解
- hdu 4474 bfs
- java 路径分隔符
- 递归
- Android学习笔记--RecycleView用法
- POJ 2392 Space Elevator 排序+多重背包
- Android handler示例
- linux jdk安装配置
- 记毕业感悟160727
- WebGL学习笔记(二)
- 弹出框日历自己写的...
- AndroidStudio 快捷键 Ctrl+Alt+left 不能用
- Android插件-动态加载