RecyclerView的使用详解
16lz
2021-01-24
RecyclerView的使用详解
RecyclerView的Adapter:
1.item的重用无需关心;
2.强制要求实现一个ViewHolder;
创建一个类(MyAdapter)继承于RecyclerView.Adapter;
定义一个ViewHolder;
搭建基础Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>{ private Context mContext; private List<String> dataList = new ArrayList<>(); public MyAdapter(Context context, List<String> data) { mContext = context; dataList = data; } /** * 当解析布局这样子写时: * View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, parent, false); * item中最外层布局的layout属性才起作用;eg: * * 当解析布局这样子写时: * View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, null); * item中最外层布局的layout属性则不起作用; * * viewType:多布局使用的; * * @param parent * @param viewType * @return */
@NonNull @Override public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, parent, false); return new MyHolder(view); } @Override public void onBindViewHolder(@NonNull MyHolder holder, int position) { holder.textView.setText(dataList.get(position)); } @Override public int getItemCount() { return dataList.size(); } public class MyHolder extends RecyclerView.ViewHolder { private TextView textView; /** * 接收Item的布局对象 * * @param itemView */ public MyHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.textView); } }}
使用RecyclerView:
private MyAdapter myAdapter;private RecyclerView listRecyclerView;private List<String> listData = new ArrayList<>();listRecyclerView = findViewById(R.id.recycler_view);//设置布局管理器;listRecyclerView.setLayoutManager(new LinearLayoutManager(this));//new LinearLayoutManager;跟ListView一样的排列方式;//LinearLayoutManager.HORIZONTAL:设置滑动的方向为横向;//LinearLayoutManager.VERTICAL:设置滑动的方向为纵向;//reverseLayout-->false:设置数据正序排列还是反序排列;eg:1...26为正序设置为false;26..1为反序设置为true;listRecyclerView.setLayoutManager( new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));//new GridLayoutManager:跟GridView一样的排列方式;//3-->spanCount:如果方向为LinearLayoutManager.VERTICAL:则是设置有多少列;// LinearLayoutManager.HORIZONTAL:则是设置有多少行;//LinearLayoutManager.HORIZONTAL:设置方向;//reverseLayout-->false:设置数据正序排列还是反序排列;eg:1...26为正序设置为false;26..1为反序设置为true;listRecyclerView.setLayoutManager( new GridLayoutManager(this, 3, LinearLayoutManager.HORIZONTAL, false));//new StaggeredGridLayoutManager:瀑布流的排列方式;即当每个item需要显示的数据大小不一样时,则每个item的高度不会对齐;//3-->spanCount:如果方向为LinearLayoutManager.VERTICAL:则是设置有多少列;// LinearLayoutManager.HORIZONTAL:则是设置有多少行;//LinearLayoutManager.HORIZONTAL:设置方向;listRecyclerView.setLayoutManager( new StaggeredGridLayoutManager(3, LinearLayout.HORIZONTAL));myAdapter = new MyAdapter(this, listData);listRecyclerView.setAdapter(myAdapter;
ps–>item布局的最外层布局必须使用wrap_content;如果使用match_parent则会一个Item占一页;
getAdapterPosition():获得适配器的下标;当前点击的Item的下标;
ps:瀑布流的排列形式;
ReyclerView的Item的点击事件:
1.在Adapter中创建:
第一种创建方式:
public class MyHolder extends RecyclerView.ViewHolder{ private TextView textView; /** * 接收Item的布局对象 * * @param itemView */ public MyHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.textView); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemClickListener != null) { onItemClickListener.onItemClick(v, getAdapterPosition()); } } }); }}private OnItemClickListener onItemClickListener;public void setOnItemClickListener(OnItemClickListener onItemClickListener){ this.onItemClickListener = onItemClickListener;}public interface OnItemClickListener{ void onItemClick(View view, int position);}
2.第二种创建方式:
@Overridepublic void onBindViewHolder(@NonNull MyHolder holder, int position){ holder.textView.setText(dataList.get(position)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemClickListener != null) { onItemClickListener.onItemClick(v, position); } } });}private OnItemClickListener onItemClickListener;public void setOnItemClickListener(OnItemClickListener onItemClickListener){ this.onItemClickListener = onItemClickListener;}public interface OnItemClickListener{ void onItemClick(View view, int position);}
在MainActivity中使用:
myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener(){ @Override public void onItemClick(View view, int position) { //添加数据单条数据时; //position-->添加在position的位置; //使用notifyItemInserted;则只会刷新添加的那条数据; myAdapter.notifyItemInserted(position); //添加多条数据; //position-->从position的位置开始添加; //itemCount:5-->一共需要添加几条; myAdapter.notifyItemRangeInserted(position, 5); //删除单条数据; //position-->删除在position的位置的数据; myAdapter.notifyItemRemoved(position); //删除多条数据; //position-->从position的位置开始删除; //itemCount:5-->一共需要删除几条; myAdapter.notifyItemRangeRemoved(position, 5); //点击当前的position,使数据移到最顶端; String str = listData.remove(position); listData.add(str); myAdapter.notifyItemMoved(position, 0); //修改数据; myAdapter.notifyItemChanged(position); //批量修改 myAdapter.notifyItemRangeChanged(position, 6); //滚动到第几个下标; listRecyclerView.scrollToPosition(position); }});
设置显示的动画:
listRecyclerView.setItemAnimator(new DefaultItemAnimator());
设置每个item的分割线:
listRecyclerView.addItemDecoration(new MyItemDecoration(this));
自定义一个分割线的类:
public class MyItemDecoration extends RecyclerView.ItemDecoration{ /** * 系统的Drawable,用来话ListView的分割线的资源 */ private int[] ATTR = {android.R.attr.listDivider}; /** * 分割线的资源; */ private Drawable drawable; public MyItemDecoration(Context context) { //获得Drawable资源的属性; TypedArray typedArray = context.obtainStyledAttributes(ATTR); //获取第一个Drawable; drawable = typedArray.getDrawable(0); //释放资源; typedArray.recycle(); } /** * 分割线的绘制; * * @param c * @param parent * @param state */ @Override public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.onDraw(c, parent, state); //parent.getChildCount()-->获取一共有多少个Item; for (int i = 0; i < parent.getChildCount(); i++) { //最后一个不用绘制分割线; if (i == parent.getChildCount() - 1) { return; } //获取第i个ItemView; View itemView = parent.getChildAt(i); //获取item的左边的坐标; int left = itemView.getLeft(); //获取item的下边的坐标; int top = itemView.getBottom(); //获取item的右边的坐标; int right = itemView.getRight(); //获取分割线的下边的坐标;drawable.getIntrinsicHeight()-->分割线资源的高度; int bottom = itemView.getBottom() + drawable.getIntrinsicHeight(); //设置分割线的坐标; drawable.setBounds(left, top, right, bottom); //绘制画布; drawable.draw(c); } } /** * 设置每个Item需要预留出来的空间,供分割线使用; * * @param outRect * @param view * @param parent * @param state */ @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); // drawable.getIntrinsicHeight():底部需要预留出来的空间; outRect.set(0, 0, 0, drawable.getIntrinsicHeight()); }}
更多相关文章
- android ConstraintLayout百分比适配
- Android(安卓)使用JAVA代码控制UI界面
- Android(安卓)工程目录简单结构
- android 长按,快速按的按键处理
- Android文章目录
- SavedStateHandle的使用,临时保存数据
- Android中界面中有多个edittext,如何默认让第二个获取焦点
- 【转】 Android(安卓)Action大全
- android 动态改变控件的位置的方法