在开发项目时,要想自己的项目布局好看点避免不了要使用RecylerView(比ListView要高级应该都知道吧,至于区别不知道的自行百度)
在使用了好多次RecylerView后你脑海中就会浮现出一个使用RecylerView的框架,就好像数学公式一样,废话不多说,直接上代码,代码很简单,基本都写了注释
首先让我们一起看看一个无任何内容的RecylerView该怎么写吧
使用RecylerView需要导依赖包
implementation 'androidx.recyclerview:recyclerview:1.1.0'
看我项目结构
?
实体类Book
public class Book {
public String title; // 标题
public int content; //内容(我这里放的是图片)
}
MainActivity代码如下
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
MyAdapter mMyAdapter ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerview);
mMyAdapter = new MyAdapter(MainActivity.this);
mRecyclerView.setAdapter(mMyAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
mRecyclerView.setLayoutManager(layoutManager);
}
}
MainActivity布局activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
MyAdapter代码如下
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHoder> {
private LayoutInflater mInflater; //声明布局填充器
public MyAdapter(Context context) {
mInflater = LayoutInflater.from(context); //获取布局服务
}
//用于创建ViewHolder实例,并加载布局
@NonNull
@Override
public MyViewHoder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate( R.layout.item_recy, parent, false);
MyViewHoder myViewHoder = new MyViewHoder(view);
return myViewHoder;
}
//RecyclerView子项的个数
@Override
public void onBindViewHolder(@NonNull MyViewHoder holder, @SuppressLint("RecyclerView") int position) {
}
//RecyclerView子项的个数
@Override
public int getItemCount() {
return 0;
}
//自定义内部类 ViewHolder
public static class MyViewHoder extends RecyclerView.ViewHolder {
public MyViewHoder(@NonNull View itemView) {
super(itemView);
}
}
}
MyAdapter布局item_recy.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:id="@+id/item">
<ImageView
android:id="@+id/imageView"
android:layout_width="80dp"
android:layout_height="100dp"
android:text="内容"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"/>
<Button
android:id="@+id/button"
android:layout_width="60dp"
android:layout_height="40dp"
android:text="按钮"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"/>
</LinearLayout>
这就是一个没写任何内容的RecylerView,不要死记,写多了就记住了,运行结果当然就是空白了,因为填充任何数据,我这就不展示运行结果了
接下来我们就往里面添加一些简单的数据来看看它到底是什么样子
项目结构还是这个
?
实体类Book
public class Book {
public String title; // 标题
public int content; //内容(我这里放的是图片)
}
MainActivity代码如下
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
MyAdapter mMyAdapter ;
List<Book> mBookList = new ArrayList<>();
private int[] images = {R.drawable.img};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerview);
// 初始化一些数据
for (int i = 0; i < 50; i++) {
Book news = new Book();
news.title = "标题" + i;
news.content = images[0];
mBookList.add(news);
}
mMyAdapter = new MyAdapter(MainActivity.this,mBookList);
mRecyclerView.setAdapter(mMyAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this); //获取 线性布局管理器 对象
layoutManager.setOrientation(RecyclerView.HORIZONTAL); //设置水平滑动,不设置则是竖直上下滑动
mRecyclerView.setLayoutManager(layoutManager);
}
}
MainActivity布局activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
MyAdapter代码如下
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHoder> {
private Context mContext; //声明上下文
private LayoutInflater mInflater; //声明布局填充器
List<Book> mBookList = new ArrayList<>(); //数据源
public MyAdapter(Context context,List<Book> list) {
mInflater = LayoutInflater.from(context); //获取布局服务
this.mContext = context; //获取activity传来的上下文,在MyAdapter需要用到
this.mBookList = list; //获取activity传来的数据
}
//用于创建ViewHolder实例,并加载布局
@NonNull
@Override
public MyViewHoder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate( R.layout.item_recy, parent, false);
MyViewHoder myViewHoder = new MyViewHoder(view);
return myViewHoder;
}
//RecyclerView子项的个数
@Override
public void onBindViewHolder(@NonNull MyViewHoder holder, @SuppressLint("RecyclerView") int position) {
Book book = mBookList.get(position);
holder.mTitleTv.setText(book.title);
holder.mTitleContent.setImageResource(book.content);
}
//RecyclerView子项的个数
@Override
public int getItemCount() {
return mBookList.size();
}
//自定义内部类 ViewHolder
public static class MyViewHoder extends RecyclerView.ViewHolder {
Button button;
TextView mTitleTv;
ImageView mTitleContent;
LinearLayout item;
public MyViewHoder(@NonNull View itemView) {
super(itemView);
mTitleTv = itemView.findViewById(R.id.textView);
mTitleContent = itemView.findViewById(R.id.imageView);
button = itemView.findViewById(R.id.button);
item = itemView.findViewById(R.id.item);
}
}
}
MyAdapter布局item_recy.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:id="@+id/item">
<ImageView
android:id="@+id/imageView"
android:layout_width="80dp"
android:layout_height="100dp"
android:text="内容"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"/>
<Button
android:id="@+id/button"
android:layout_width="60dp"
android:layout_height="40dp"
android:text="按钮"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"/>
</LinearLayout>
LinearLayoutManager 线性布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this); //获取 线性布局管理器 对象
layoutManager.setOrientation(RecyclerView.HORIZONTAL); //设置水平滑动,不设置则是竖直上下滑动
mRecyclerView.setLayoutManager(layoutManager);
运行结果展示,这里可以左右滑动,因为我在MainActivity中写了这行代码
layoutManager.setOrientation(RecyclerView.HORIZONTAL); //设置水平滑动,不设置则是竖直上下滑动
?不写那行代码的话,也就是不设置水平滑动,运行结果如下,可以上下滑动,还有
GridLayoutManager 网格布局管理器
(只需将LinearLayoutManager改为GridLayoutManager,数字3是item),设置了水平滑动,可以水平滑动
GridLayoutManager layoutManager = new GridLayoutManager (MainActivity.this,3); //获取 线性布局管理器 对象
layoutManager.setOrientation(RecyclerView.HORIZONTAL); //设置水平滑动,不设置则是竖直上下滑动
mRecyclerView.setLayoutManager(layoutManager);
运行结果
不设置水平,就是上下滑动,运行结果为
?到此 RecylerView 的基本布局就说玩了,想要了解更多可以自行查找相关资料
光会布局可不行,还要知道如何为 RecylerView 的 item 添加点击事件,这里指的点击事件不是仅仅指的那个简单的 setOnClickListener ,比如我点击一下item或item里的button,然后修改数据,但是你就会发现,数据源头在哪,是不是在MainActivity中,MainActivity传给MyAdapter的。
现在你是在MyAdapter获取item对象设置点击事件,然后要修改的数据又在MainActivity。
反过来看MainActivity有要修改的数据,但是获取不到item对象。
是不是发现了问题,其实要解决也很简单,就是用接口回调的方法来实现,MyAdapter中定义接口,MainActivity中new一个接口对象并重写里面的方法,当我们点击item后,就会调到MainActivity中重写的方法。
MyAdapter代码如下(添加了接口和点击事件)
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHoder> {
private Context mContext; //声明上下文
private LayoutInflater mInflater; //声明布局填充器
List<Book> mBookList = new ArrayList<>(); //数据源
public MyAdapter(Context context,List<Book> list) {
mInflater = LayoutInflater.from(context); //获取布局服务
this.mContext = context; //获取activity传来的上下文,在MyAdapter需要用到
this.mBookList = list; //获取activity传来的数据
}
//接口
private ClickInterface clickInterface;
//*********************点击事件*****************************************//
public void setOnclick(ClickInterface clickInterface) {
this.clickInterface = clickInterface;
}
//回调接口
public interface ClickInterface {
void onButtonClick(View view, int position);
void onItemClick(View view, int position);
}
//*********************点击事件*****************************************//
//用于创建ViewHolder实例,并加载布局
@NonNull
@Override
public MyViewHoder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate( R.layout.item_recy, parent, false);
MyViewHoder myViewHoder = new MyViewHoder(view);
return myViewHoder;
}
//RecyclerView子项的个数
@Override
public void onBindViewHolder(@NonNull MyViewHoder holder, @SuppressLint("RecyclerView") int position) {
Book book = mBookList.get(position);
holder.mTitleTv.setText(book.title);
holder.mTitleContent.setImageResource(book.content);
//*********************点击事件*****************************************//
//Button点击事件
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (clickInterface != null) {
clickInterface.onButtonClick(v, position);
}
}
});
//item点击事件
holder.item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (clickInterface != null) {
clickInterface.onItemClick(v, position);
}
}
});
//*********************点击事件*****************************************//
}
//RecyclerView子项的个数
@Override
public int getItemCount() {
return mBookList.size();
}
//自定义内部类 ViewHolder
public static class MyViewHoder extends RecyclerView.ViewHolder {
Button button;
TextView mTitleTv;
ImageView mTitleContent;
LinearLayout item;
public MyViewHoder(@NonNull View itemView) {
super(itemView);
mTitleTv = itemView.findViewById(R.id.textView);
mTitleContent = itemView.findViewById(R.id.imageView);
button = itemView.findViewById(R.id.button);
item = itemView.findViewById(R.id.item);
}
}
}
MainActivity代码如下(添加了点击事件和重写了MyAdapter的接口的方法)
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
MyAdapter mMyAdapter ;
List<Book> mBookList = new ArrayList<>();
private int[] images = {R.drawable.img};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerview);
// 初始化一些数据
for (int i = 0; i < 50; i++) {
Book news = new Book();
news.title = "标题" + i;
news.content = images[0];
mBookList.add(news);
}
mMyAdapter = new MyAdapter(MainActivity.this,mBookList);
mRecyclerView.setAdapter(mMyAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager (MainActivity.this); //获取 线性布局管理器 对象
layoutManager.setOrientation(RecyclerView.HORIZONTAL); //设置水平滑动,不设置则是竖直上下滑动
mRecyclerView.setLayoutManager(layoutManager);
//添加点击事件
mRecyclerView.post(new Runnable() {
@Override
public void run() {
mMyAdapter.setOnclick(new MyAdapter.ClickInterface() {
@Override
public void onButtonClick(View view, int position) {
Toast.makeText(view.getContext(), "你点击了button" , Toast.LENGTH_SHORT).show();
}
@Override
public void onItemClick(View view, int position) {
Toast.makeText(view.getContext(), "你点击了item" , Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
运行结果
|