recyclerView的写法
导入到工程中
方式一:
在你的工程上点击右键,弹出如下图片,大家看图吧
1.右键工程名,选中Modulder setting
2.点击app,再选中dependence
3.找到右边的加号,选中library
4.搜索框中输入recycler
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020092816190891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0JhcnJ5amFja2V0,size_16,color_FFFFFF,t_70#pic_center
点击ok后,这个recyclerview-v7的包就引用到自己的工程里了,也不用管那个build.jradle文件了,打开会发现已经自动填好了.
方式二:
打开app/build.gradle文件,在dependcies中添加如下内容
compile 'com.android.support:recyclerview-v7:24.0.0'
注意对于AS为3.6版本,SDK版本大于28的建议使用
implementation 'androidx.recyclerview:recyclerview:1.0.0'
recyclerView的使用
在活动中成功使用recyclerView要设置两个参数,布局和适配器。
如果要实现长按弹出菜单的功能,要调用registerForContextMenu(View v);这个函数。同时,适配器的ViewHolder类要实现响应的接口View.OnCreateContextMenuListener接口。
onBindViewHolder方法中要实现RecyclerView控件中每一个item View的大部分功能。因为 onBindViewHolder的执行是在创建ViewHolder,且已知itemView的个数后才调用的。对于每一个item进行数据绑定时都会调用一次。
rvContract = (RecyclerView) findViewById(R.id.rvContract);
//传入线性布局
rvContract.setLayoutManager(new LinearLayoutManager(this));
mList = new ArrayList<>();
mAdapter = new ContactAdapter(this, mList);
rvContract.setAdapter(mAdapter);
registerForContextMenu(rvContract);
/**
* 长按item弹出菜单后,点击某一菜单项会回调这一方法
* item中带有一个intent属性。
* itemId对应着菜单的id
*
* @param item 所点击的菜单项
* @return
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0://修改
break;
case 1://删除
deleteContact(item);
break;
}
return super.onContextItemSelected(item);
}
实现rv的适配器类,由于rv的封装就要求有viewHolder类,故可以先写内部静态类ContractViewHolder extends RecyclerView.ViewHolder。
/**
* @ 功能适配器中必须要有实体类,也是bean
* 1.数据的绑定,2.创建viewHolder--布局加载器--上下文对象
* Ctreate by barry on 2020/9/20.
*/
public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContractViewHolder> {
private Context mContext;//null
private List<ContactBean> mList;//null
private LayoutInflater mInflater;//null
private static final String POSITION_KEY ="POSITION_KEY";
public ContactAdapter(Context mContext, List<ContactBean> mList) {
this.mContext = mContext;
this.mList = mList;
mInflater = LayoutInflater.from(mContext);
}
/**
* 创建ViewHolder实例,并将item布局加载进入
* @param parent
* @param viewType
* @return
*/
@NonNull
@Override
public ContractViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//加载item布局
View view = mInflater.inflate(R.layout.recyclerview_item_contact,parent,false);
ContractViewHolder viewHolder = new ContractViewHolder(view);
return viewHolder;
}
/**
* 对vieholder对象进行数据赋值
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(@NonNull ContractViewHolder holder, int position) {
ContactBean contact = mList.get(position);
holder.tvName.setText(contact.getName());
holder.tvPhone.setText(contact.getPhone());
}
/**
* 统计item个数
* 如果直接返回一个固定的数字,就会有一些空的item项
* @return
*/
@Override
public int getItemCount() {
return mList.size();
}
static class ContractViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener{
private TextView tvName;//null
private TextView tvPhone;//null
public ContractViewHolder(@NonNull View itemView) {
super(itemView);
tvName = (TextView)itemView.findViewById(R.id.tv_name);
tvPhone = (TextView)itemView.findViewById(R.id.tv_phone);
//由于recycleView没有实现长按弹出菜单的接口,要在ViewHolder中自己实现该接口
//setOnCreateContextMenuListener(OnCreateContextMenuListener l)
// 由于ContractViewHolder已经实现该接口,故直接传入this
itemView.setOnCreateContextMenuListener(this);
}
//创建响应的菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
//获取当前所按的item的下标,回传到MainActivity中供onContextItemSelected使用。
int position = getAdapterPosition();
Intent intent = new Intent();//这里不需要使用intent,来跳转
intent.putExtra(POSITION_KEY,position);
menu.setHeaderTitle("编剧");
//菜单的选项时通过add来直接添加,通过setIntent(),让每一个MenuItem自带了一个intent
menu.add(0,0,0,"修改").setIntent(intent);
menu.add(0,1,0,"删除").setIntent(intent);
}
}
}
创建一个实体类来存储item内容。
注意,为了让bean的数据能在活动之间相互传输,要实现序列化1.seriable 2.Parcelable。安卓提供了序列化的插件。
参考如何使用Parcelable完成序列化操作
/**由于要在不同的活动之间进行传递,该类必须实现序列化1.seriable 2.Parcelable
* @ 功能
* Ctreate by barry on 2020/9/22.
*/
public class ContactBean implements Parcelable {
private int id;
private String name;
private String phone;
item的偏移,实现更好的视觉效果。
主要是调用addItemDecoration()方法,该方法需要传入一个ItemDecoration对象。
在安卓中,系统已经实现了ItemDecoration的实现类,DividerItemDecoration类。
DividerItemDecoration.HORIZONTAL
表示在水平列之间加间隔
DividerItemDecoration.VERTICAL
表示在竖直列之间加间隔
mRvGrid.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.HORIZONTAL));
该类的缺点:每个偏移的间隔只有1dp.如果要大一点的间隔偏移,还是要自己定义一个类来继承ItemDecoration。
GridSpaceItemDecoration.java
public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {
private int mSpace;
public GridSpaceItemDecoration(int mSpace) {
this.mSpace = mSpace;
}
/**
* 设置itemView的偏移量,每一个itemView都会调用这一函数
* @param outRect Item的矩形边界对象,里面由各个item的各边偏移量。
* @param view ItemView
* @param parent RecyclerView
* @param state RecyclerView的状态
*/
@Override
public void getItemOffsets(@NonNull Rect outRect,
@NonNull View view, @NonNull RecyclerView parent,
@NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
//每一个itemView 左侧都有一个距离
outRect.left = mSpace;
}
}
偏移量会使得未偏移的itemView的宽度或者高度会减少偏移量dp.
效果如下
同时可以通过移动View,来使第一幅的左边框消失。
private void getRecyclerViewOffset(RecyclerView parent){
// View 的margin
// margin 为正 ,则View会距离边界产生一个距离
// margin 为负 ,则View会超出边界产生一个距离
LinearLayout.LayoutParams layoutParams= (LinearLayout.LayoutParams) parent.getLayoutParams();
layoutParams.leftMargin = -mSpace;
parent.setLayoutParams(layoutParams);
}
在构造器中调用该函数。
public GridSpaceItemDecoration(int mSpace, RecyclerView parent) {
this.mSpace = mSpace;
getRecyclerViewOffset(parent);
}
在MainActivity中调用
getResources().getDimensionPixelSize(R.dimen.albumMarginSize),获取定义在dimen.xml的数据大小。
mRvGrid.addItemDecoration(new GridSpaceItemDecoration(getResources().
getDimensionPixelSize(R.dimen.albumMarginSize),mRvGrid));
实现ViewHold的内部点击事件
RecyclerView没有setOnItemClickListener这样的注册监听器方法,而是需要我们给子项具体的View去注册点击事件。修改适配器FruitAdapter的onCreateViewHolder方法。或者在bindViewHold()进行注册
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHold {
val binding=FruitItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
val viewHolder=ViewHold(binding)
viewHolder.fruitName.setOnClickListener {}
viewHolder.fruitImage.setOnClickListener{}
return viewHolder
}