RecyclerView
概义
RecyclerView是什么
从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活。RecyclerView的官方定义如下:
A flexible view for providing a limited window into a large data set.
从定义可以看出,flexible(可扩展性)是RecyclerView的特点。
RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字Recyclerview即回收view也可以看出。
和ListView相比
RecyclerView并不会完全替代ListView(这点从ListView没有被标记为@Deprecated可以看出),两者的使用场景不一样。但是RecyclerView的出现会让很多开源项目被废弃,例如横向滚动的ListView, 横向滚动的GridView, 瀑布流控件,因为RecyclerView能够实现所有这些功能。
RecyclerView封装了viewholder的回收复用,也就是说RecyclerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
·提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecyclerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。
·设置布局管理器以控制Item的布局方式,横向、竖向以及瀑布流方式
·可设置Item的间隔样式(可绘制)
通过继承RecyclerView的ItemDecoration这个类,然后针对自己的业务需求去书写代码。
·可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecyclerView有其自己默认的实现。
但是关于Item的点击和长按事件,需要用户自己去实现。
常用方法
1.RecyclerView横向滑动:
LinearLayoutManager.HORIZONTAL横向滑动LinearLayoutManager.VERTICAL垂直滑动
2.RecyclerView.Adapter中刷新方法区别:
notifyDataSetChanged();整体刷新+没有动画效果
notifyItemInserted(int position,Object data):有动画效果+添加一条数据在position位置
notifyItemRemoved(position);有动画效果+删除一条数据并刷新
注意:当添加和删除的时候,要更新下标,不然有错位现象
先在集合中删除要删除的数据
之后
myRecyclerViewAdapter.notifyItemRangeChanged(0,arrayList.size());
3.RecyclerView多布局展示:
public int getItemViewType(int position)返回当前数据的itemview类型
4.RecyclerView常见方法:
LinearLayoutManager:recyclerview线性管理器(垂直水平方向);
GridLayoutManager:网格布局管理器;
StaggeredGridLayoutManager:瀑布流布局管理器;
RecyclerView.setLayoutManager(LayoutManager manager):添加布局管理器
RecyclerView.addItemDecoration(ItemDecoration decoration):添加分割线
RecyclerView.setItemAnimator(ItemAnimator animator):添加动画方法
RecyclerView.setAdapter(Adapter adapter):添加适配器
依赖
//RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'
//万能适配器
//在整个项目的builder.gradle中的allprojects的repositories写入
maven {
url 'https://jitpack.io'
}
//builder.gradle---导入依赖
implementation'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.4
implementation 'com.android.support:recyclerview-v7:28.0.0'
代码
普通的适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
ArrayList<String> list;
Context context;
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new MyViewHolder(LayoutInflater.from(context)
.inflate(R.layout.myviewholder_layout,viewGroup,false));
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
Glide.with(context).load(list.get(i)).into(myViewHolder.img);
}
@Override
public int getItemCount() {
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
ImageView img;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
img=itemView.findViewById(R.id.img);
}
}
}
myviewholder 的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//-----centerCrop 填充不拉伸
<ImageView
android:scaleType="centerCrop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/img"
/>
</LinearLayout>
普通的主函数代码
public class MainActivity extends AppCompatActivity {
RecyclerView rv;
ArrayList<String> list=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv=findViewById(R.id.rv);
rv.setAdapter(new MyAdapter(list,this));
rv.setLayoutManager(new LinearLayoutManager(this));//线性布局
rv.setLayoutManager(new GridLayoutManager(this,2));//网格布局
rv.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));//垂直瀑布流布局
}
}
多布局
重写getItemViewType方法
代码
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
ArrayList<Bean> list;
Context context;
public MyAdapter(ArrayList<Bean> list, Context context) {
this.list = list;
this.context = context;
}
@Override
public int getItemViewType(int position) {
return list.get(position).getType();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
if(i==0){
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.myviewholder_layout,viewGroup,false));
}else {
return new MyViewHolder2(LayoutInflater.from(context).inflate(R.layout.myviewholder_layout2,viewGroup,false));
}}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
if(getItemViewType(i)==0) {
MyViewHolder myViewHolder = (MyViewHolder) viewHolder;
Glide.with(context).load(list.get(i).getImg_id()).apply(RequestOptions.bitmapTransform(new CircleCrop())).into(myViewHolder.img);
myViewHolder.tv.setText(list.get(i).getText());
}else {
MyViewHolder2 myViewHolder2 = (MyViewHolder2) viewHolder;
Glide.with(context).load(list.get(i).getImg_id()).apply(RequestOptions.bitmapTransform(new CircleCrop())).into(myViewHolder2.img2);
myViewHolder2.tv2.setText(list.get(i).getText());
}
}
@Override
public int getItemCount() {
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
ImageView img;
TextView tv;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
img=itemView.findViewById(R.id.img);
tv=itemView.findViewById(R.id.tv);
}
}
class MyViewHolder2 extends RecyclerView.ViewHolder{
ImageView img2;
TextView tv2;
public MyViewHolder2(@NonNull View itemView) {
super(itemView);
img2=itemView.findViewById(R.id.img2);
tv2=itemView.findViewById(R.id.tv2);
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
RecyclerView rv;
ArrayList<Bean> list=new ArrayList<>();
MyAdapter myAdapter;
EditText et1;
Button bt1;
LinearLayoutManager linearLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv=findViewById(R.id.rv);
list.add(new Bean(0,R.drawable.pp,"道友好啊,在下云梦江氏魏无羡"));
list.add(new Bean(1,R.drawable.zxf,"仙友好,在下青云门张小凡"));
list.add(new Bean(0,R.drawable.pp,"我生平很惨的,被发小杀死了"));
list.add(new Bean(1,R.drawable.zxf,"我也不怎么好,被师尊杀死了"));
list.add(new Bean(0,R.drawable.pp,"我重生后成为了人闻人骂的夷陵老祖"));
list.add(new Bean(1,R.drawable.zxf,"我重生后成为了人见人怕的鬼厉"));
list.add(new Bean(0,R.drawable.pp,"我幸运的是有蓝湛"));
list.add(new Bean(1,R.drawable.zxf,"碧瑶是我的执念"));
list.add(new Bean(0,R.drawable.pp,"我们最终可以一起行侠江湖夜猎了"));
list.add(new Bean(1,R.drawable.zxf,"碧瑶睡了十年了,也该醒醒了"));
myAdapter=new MyAdapter(list,this);
rv.setAdapter(myAdapter);
linearLayoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(linearLayoutManager);//线性布局
bt1=findViewById(R.id.bt1);
et1=findViewById(R.id.et1);
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
list.add(new Bean(1,R.drawable.zxf,et1.getText().toString()));
myAdapter.notifyDataSetChanged();
linearLayoutManager.scrollToPosition(list.size()-1);
et1.setText("");
}
});
}
}
添加分割线
recyclerview的点击事件(适配器中接口回调)
//适配器中
RecycleListener recycleListener;
public void setRecycleListener(RecycleListener recycleListener) {
this.recycleListener = recycleListener;
}
//onBindViewHolder中
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("#######","第一个进来了");
recycleListener.onclick(i);
}
});
//mainAcitvity中
myAdapter2.setRecycleListener(new RecycleListener() {
@Override
public void onclick(int position) {
Toast.makeText(Main2Activity.this,list.get(position).getText()+"",Toast.LENGTH_SHORT).show();
}
});
recycleview添加动画
万能适配器
主函数
public class Main5Activity extends AppCompatActivity {
RecyclerView rv;
ArrayList<Bean4> list=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
rv=findViewById(R.id.rv);
for(int i=0;i<15;i++){
Bean4 bean4 = new Bean4();
bean4.setTitle("这是第"+i+"条信息");
list.add(bean4);
}
MyQuickAdapter myQuickAdapter = new MyQuickAdapter(R.layout.myquicj_layout, list);
rv.setAdapter(myQuickAdapter);
rv.setLayoutManager(new LinearLayoutManager(this));
//设置点击事件
myQuickAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
Toast.makeText(Main5Activity.this,position+"被点击了",Toast.LENGTH_SHORT).show();
}
});
//设置子控件的点击事件
myQuickAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
if(view.getId()==R.id.tvv){
Toast.makeText(Main5Activity.this,"点击了文字",Toast.LENGTH_SHORT).show();
}else if(view.getId()==R.id.imgg){
Toast.makeText(Main5Activity.this,"点击了图片",Toast.LENGTH_SHORT).show();
}
}
});
}
}
BaseQuickAdapter+点击事件
public class MyQuickAdapter extends BaseQuickAdapter<Bean4,BaseViewHolder> {
public MyQuickAdapter(int layoutResId, @Nullable List<Bean4> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, Bean4 item) {
helper.setText(R.id.tvv,item.getTitle())
.addOnClickListener(R.id.tvv)
.addOnClickListener(R.id.imgg);
ImageView view = helper.getView(R.id.imgg);
Glide.with(mContext).load(item.getPic())
.apply(RequestOptions.bitmapTransform(new CircleCrop())).into(view)
}
}
多布局万能适配器
布局
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="8"
android:id="@+id/rvv"
></android.support.v7.widget.RecyclerView>
适配器
public class MyAdapter2 extends BaseQuickAdapter<Bean2,BaseViewHolder> {
public MyAdapter2( @Nullable List<Bean2> data) {
super( data);
setMultiTypeDelegate(new MultiTypeDelegate<Bean2>() {
@Override
protected int getItemType(Bean2 bean2) {
return bean2.getType();
}
});
getMultiTypeDelegate()
.registerItemType(0,R.layout.left_layout)
.registerItemType(1,R.layout.right_layout);
}
@Override
protected void convert(BaseViewHolder helper, Bean2 item) {
int itemViewType = helper.getItemViewType();
if(itemViewType==0){
helper.setText(R.id.tv_left,item.getMess())
.setImageResource(R.id.img_left,R.mipmap.ic_launcher);
}else if(itemViewType==1){
helper.setText(R.id.tv_right,item.getMess())
.setImageResource(R.id.img_right,R.mipmap.ic_launcher_round);
}
}
}
bean类
public class Bean2 {
int type;
String mess;
public Bean2(int type, String mess) {
this.type = type;
this.mess = mess;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getMess() {
return mess;
}
public void setMess(String mess) {
this.mess = mess;
}
}
主函数
RecyclerView recyclerView;
recyclerView=findViewById(R.id.rvv);
list.add(new Bean2(1,obj));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
myAdapter2 = new MyAdapter2(list);
recyclerView.setAdapter(myAdapter2);