Android初识RecyclerView 添加分割线、单击事件、长按事件
2017-01-18 16:15
471 查看
一、概述
RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能。
优点:
RecyclerView封装了viewholder的回收复用
提供了一种插拔式的体验,高度的解耦,异常的灵活
通过布局管理器LayoutManager可以控制其显示的方式
通过ItemDecoration可以控制Item间的间隔(可绘制)
通过ItemAnimator可以控制Item增删的动画
缺点:
点击、长按事件需要自己实现
RecyclerView.Adapter需要实现3个方法:
1.onCreateViewHolder()
这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
2.onBindViewHolder()
这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。
3.getItemCount()
这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。
在项目使用需要添加依赖:
二、普通列表
1.实现效果图
2.核心代码
列表页面RecyclerViewActivity.java
布局文件activity_recyclerview.xml
适配器StudentListAdapter.java
添加分割线通用工具类ItemDivider.java
添加单击、长按事件通用工具类RecyclerItemClickListener.java
三、网格列表
1.实现效果图
RecyclerView在普通列表和网格列表的切换上面做的比较方便,只需要修改LayoutManager参数即可。
四、源代码下载
http://download.csdn.net/detail/chenzheng8975/9740701
RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能。
优点:
RecyclerView封装了viewholder的回收复用
提供了一种插拔式的体验,高度的解耦,异常的灵活
通过布局管理器LayoutManager可以控制其显示的方式
通过ItemDecoration可以控制Item间的间隔(可绘制)
通过ItemAnimator可以控制Item增删的动画
缺点:
点击、长按事件需要自己实现
RecyclerView.Adapter需要实现3个方法:
1.onCreateViewHolder()
这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
2.onBindViewHolder()
这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。
3.getItemCount()
这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。
在项目使用需要添加依赖:
compile 'com.android.support:recyclerview-v7:24.2.1'
二、普通列表
1.实现效果图
2.核心代码
列表页面RecyclerViewActivity.java
package com.czhappy.recyclerviewdemo.activity; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.Toast; import com.czhappy.recyclerviewdemo.R; import com.czhappy.recyclerviewdemo.adapter.StudentListAdapter; import com.czhappy.recyclerviewdemo.listener.RecyclerItemClickListener; import com.czhappy.recyclerviewdemo.model.Student; import com.czhappy.recyclerviewdemo.view.ItemDivider; import java.util.ArrayList; import java.util.List; import static com.czhappy.recyclerviewdemo.R.id.recyclerView; /** * Description: * User: chenzheng * Date: 2017/1/18 0018 * Time: 10:42 */ public class RecyclerViewActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private List<Student> list; private StudentListAdapter adapter; private int flag = 1; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recyclerview); flag = getIntent().getIntExtra("flag", 1); initData(); initView(); } private void initData() { list = new ArrayList<Student>(); for (int i = 0; i < 20; i++) { Student s = new Student(); s.setUserName("我是学生"+i); list.add(s); } } private void initView() { mRecyclerView = (RecyclerView) this.findViewById(recyclerView); //设置布局管理器 if(flag==1){//普通列表 mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); }else{//网格列表 mRecyclerView.setLayoutManager(new GridLayoutManager(this,2)); } //设置adapter adapter = new StudentListAdapter(this); mRecyclerView.setAdapter(adapter); //设置Item增加、移除动画 mRecyclerView.setItemAnimator(new DefaultItemAnimator()); //添加分割线 mRecyclerView.addItemDecoration(new ItemDivider().setDividerWith(1).setDividerColor(0xffdddddd)); mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, mRecyclerView, new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Toast.makeText(RecyclerViewActivity.this, "单击:position="+position, Toast.LENGTH_SHORT).show(); } @Override public void onItemLongClick(View view, int position) { Toast.makeText(RecyclerViewActivity.this, "长按:position="+position, Toast.LENGTH_SHORT).show(); } })); //添加数据 adapter.setItems(list); } }
布局文件activity_recyclerview.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical"/> </LinearLayout>
适配器StudentListAdapter.java
package com.czhappy.recyclerviewdemo.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 com.czhappy.recyclerviewdemo.R; import com.czhappy.recyclerviewdemo.model.Student; import java.util.ArrayList; import java.util.List; /** * Description: * User: chenzheng * Date: 2017/1/18 0018 * Time: 11:06 */ public class StudentListAdapter extends RecyclerView.Adapter<StudentListAdapter.StudentViewHolder> { private Context mContext; private List<Student> mList = new ArrayList<Student>(); public StudentListAdapter(Context context) { this.mContext = context; } public void setItems(List<Student> list) { this.mList = list; notifyDataSetChanged(); } @Override public StudentListAdapter.StudentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { StudentViewHolder viewHolder = new StudentViewHolder(LayoutInflater.from(mContext) .inflate(R.layout.item_student_list, parent, false)); return viewHolder; } @Override public void onBindViewHolder(StudentListAdapter.StudentViewHolder holder, int position) { if(mList!=null && mList.size()>0){ Student student = mList.get(position); holder.name_tv.setText(student.getUserName()); } } @Override public int getItemCount() { return mList!=null ? mList.size() : 0; } class StudentViewHolder extends RecyclerView.ViewHolder { private TextView name_tv; public StudentViewHolder(View itemView) { super(itemView); name_tv = (TextView) itemView.findViewById(R.id.name_tv); } } }
添加分割线通用工具类ItemDivider.java
package com.czhappy.recyclerviewdemo.view; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; /** * Description: * User: chenzheng * Date: 2017/1/18 0018 * Time: 13:54 */ public class ItemDivider extends RecyclerView.ItemDecoration { private int dividerWith = 1; private Paint paint; private RecyclerView.LayoutManager layoutManager; // 构造方法,可以在这里做一些初始化,比如指定画笔颜色什么的 public ItemDivider() { initPaint(); paint.setColor(0xffff0000); } private void initPaint() { if (paint == null) { paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Paint.Style.FILL); } } public ItemDivider setDividerWith(int dividerWith) { this.dividerWith = dividerWith; return this; } public ItemDivider setDividerColor(int color) { initPaint(); paint.setColor(color); return this; } /** * 指定item之间的间距(就是指定分割线的宽度) 回调顺序 1 * @param outRect Rect to receive the output. * @param view The child view to decorate * @param parent RecyclerView this ItemDecoration is decorating * @param state The current state of RecyclerView. */ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (layoutManager == null) { layoutManager = parent.getLayoutManager(); } // 适用 LinearLayoutManager 和 GridLayoutManager if (layoutManager instanceof LinearLayoutManager) { int orientation = ((LinearLayoutManager) layoutManager).getOrientation(); if (orientation == LinearLayoutManager.VERTICAL) { // 水平分割线将绘制在item底部 outRect.bottom = dividerWith; } else if (orientation == LinearLayoutManager.HORIZONTAL) { // 垂直分割线将绘制在item右侧 outRect.right = dividerWith; } if (layoutManager instanceof GridLayoutManager) { GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) view.getLayoutParams(); // 如果是 GridLayoutManager 则需要绘制另一个方向上的分割线 if (orientation == LinearLayoutManager.VERTICAL && lp != null && lp.getSpanIndex() > 0) { // 如果列表是垂直方向,则最左边的一列略过 outRect.left = dividerWith; } else if (orientation == LinearLayoutManager.HORIZONTAL && lp != null && lp.getSpanIndex() > 0) { // 如果列表是水平方向,则最上边的一列略过 outRect.top = dividerWith; } } } } /** * 在item 绘制之前调用(就是绘制在 item 的底层) 回调顺序 2 * 一般分割线在这里绘制 * 看到canvas,对自定义控件有一定了解的话,就能想到为什么说给RecyclerView设置分割线更灵活了 * @param c Canvas to draw into * @param parent RecyclerView this ItemDecoration is drawing into * @param state The current state of RecyclerView */ @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); // 这个值是为了补偿横竖方向上分割线交叉处间隙 int offSet = (int) Math.ceil(dividerWith * 1f / 2); for (int i = 0; i < parent.getChildCount(); i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int left1 = child.getRight() + params.rightMargin; int right1 = left1 + dividerWith; int top1 = child.getTop() - offSet - params.topMargin; int bottom1 = child.getBottom() + offSet + params.bottomMargin; //绘制分割线(矩形) c.drawRect(left1, top1, right1, bottom1, paint); int left2 = child.getLeft() - offSet - params.leftMargin; int right2 = child.getRight() + offSet + params.rightMargin; int top2 = child.getBottom() + params.bottomMargin; int bottom2 = top2 + dividerWith; //绘制分割线(矩形) c.drawRect(left2, top2, right2, bottom2, paint); } } /** * 在item 绘制之后调用(就是绘制在 item 的上层) 回调顺序 3 * 也可以在这里绘制分割线,和上面的方法 二选一 * @param c Canvas to draw into * @param parent RecyclerView this ItemDecoration is drawing into * @param state The current state of RecyclerView */ @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); } }
添加单击、长按事件通用工具类RecyclerItemClickListener.java
package com.czhappy.recyclerviewdemo.listener; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; /** * Description: * User: chenzheng * Date: 2017/1/18 0018 * Time: 14:27 */ public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { public interface OnItemClickListener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } private OnItemClickListener mListener; private GestureDetector mGestureDetector; public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) { mListener = listener; mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null) { mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView)); } } }); } @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { View childView = view.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { mListener.onItemClick(childView, view.getChildAdapterPosition(childView)); } return false; } @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } }
三、网格列表
1.实现效果图
RecyclerView在普通列表和网格列表的切换上面做的比较方便,只需要修改LayoutManager参数即可。
if(flag==1){//普通列表 mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); }else{//网格列表 mRecyclerView.setLayoutManager(new GridLayoutManager(this,2)); }
四、源代码下载
http://download.csdn.net/detail/chenzheng8975/9740701
相关文章推荐
- android recyclerview的使用,添加分割线,点击,长按事件
- 精通RecyclerView:打造ListView、GridView、瀑布流;学会添加分割线、 添加删除动画 、Item点击事件
- Android RecyclerView单击、长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类
- Android中为RecyclerView添加item的点击事件
- Android RecyclerView之添加Item分割线
- Android RecyclerView单击、长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类
- Android RecyclerView单击、长按事件标准实现:基于OnItemTouchListener + GestureDetector
- 初识RecyclerView(二)——添加item的点击事件
- Android RecyclerView给Item添加点击事件
- Android组件RecyclerView添加分割线
- Android RecyclerView的使用与添加点击事件
- Android RecyclerView添加分割线
- Android RecyclerView使用(二) -给Item添加点击事件
- Android:双层嵌套ViewPager并添加单击事件
- Android中RecyclerView的item中控件的点击事件添加删除一行、上移下移一行的代码实现
- Android中Recyclerview使用6----添加条目得到点击事件和长按事件(另一种写法,较简单)
- Android RecyclerView单击、长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类
- Android中RecyclerView添加item的点击事件
- Android RecyclerView单击、长按事件标准实现:基于OnItemTouchListener + GestureDetector
- Android实现RecyclerView添加分割线的简便方法