RecyclerView是谷歌在V7包里添加的用于替代ListView的功能,同样需要适配器传入数据
一)RecyclerView的使用
使用Android Studio,创建项目之后,点击Open Moduel Settings,选择Dependies,点击右上方的加号添加recyclerview-v7,就让我们的项目引进了recyclerView.
接着创建一个简单的RecyclerView,调用setAdapter()来传入数据,三个重写方法里面使用了ViewHolder,来管理列表视图
传入了包含三行信息的字符数组
public class MainActivity extends AppCompatActivity {
private RecyclerView rv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv=new RecyclerView(this);
setContentView(rv);
rv.setLayoutManager(new LinearLayoutManager(this)); //给recyclerview设置布局
rv.setAdapter(new RecyclerView.Adapter() {
//创建我们自己的ViewHolder,用来布置我们想在列表里显示的内容
class ViewHolder extends RecyclerView.ViewHolder{
private TextView tv;
public ViewHolder(View itemView){
super(itemView);
tv= (TextView) itemView;
}
public TextView getTv(){
return tv;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(new TextView(parent.getContext())); //这里的viewholder是我们自己写的viewholder,传入TextView
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ViewHolder vh= (ViewHolder) holder; //连接Viewholder
vh.getTv().setText(data[position]); //设置子项的内容
}
@Override
public int getItemCount() {
return data.length; //返回列表子项的数量
}
String data[]=new String[]{"liujaiwei","liujiahu","haishinia"};
});
}
}
二)使用资源文件自定义列表项
比如我们使用资源文件定义子项de内容为两个TextView,一个显示标题文本,一个显示内容文本
新建xml文件,命名为cell_list,这就是我们在资源文件里自定义的列表子项布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/tv1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="@+id/tv2" />
</LinearLayout>
接着在适配器里加载这个布局,我们先把刚才写在活动里的适配器重构,在Adapter里点击右键选择Refactor-----move----ok,然后再对Adapter选择Refactor-----move----refactor,就会重构出Adapter.java文件,在这里改动一下View,构建数据集合的类型设置为自定义的cellData类型
要注意的是,这里加载子项布局的方法和之前不同的地方在于,是通过LayoutInflater来加载布局,而不是直接传入TextView;而且给TextView进行setText的时候是通过cellData类型调用成员属性title和content
这样的好处是可以自定义列表项,我们可以在cellData里设置多样的数据,在cell_list布局复杂的布局,然后通过这种方法来传给列表,那么再复杂的列表布局都可以做到,使用的更加灵活。
class MyAdapter extends RecyclerView.Adapter {
class ViewHolder extends RecyclerView.ViewHolder {
private View root;
private TextView tvTitle, tvContent;
public ViewHolder(View root) {
super(root);
tvTitle= (TextView) root.findViewById(R.id.tv1); //获取资源文件
tvContent= (TextView) root.findViewById(R.id.tv2);
}
public TextView getTvContent() {
return tvContent;
}
public TextView getTvTitle() {
return tvTitle;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//布置好布局
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_cell,null)); //加载子项布局
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ViewHolder vh = (ViewHolder) holder;
cellData cd=Data[position];
vh.getTvContent().setText(cd.content);
vh.getTvTitle().setText(cd.title);
}
@Override
public int getItemCount() {
return Data.length;
}
private cellData[] Data=new cellData[]{new cellData("新闻","莫言获得诺贝尔文学奖"),
new cellData("新闻","曹文轩获得安徒生文学奖"),
new cellData("新闻","刘家威获得矛盾文学奖")};
}
cellData类是存放子项数据的类
public class cellData {
public String title;
public String content;
public cellData(String title,String content){
this.title=title;
this.content=content;
}
}
结果如下
三)RecyclerView的布局样式
我们可以使用V7包的setLayoutManager来给RecyclerView布置不同类型的布局样式
比如
rv.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false)); //给recyclerview设置布局
这样在水平方向列表,可以左右滑动,这里的LinearLayoutManager()的三个参数,第一个是上下文,第二个是布局,有水平布局或者垂直布局,或者其他网格布局类型,第三个是是否反转,如果选择false的话,数据的顺序是正常的,选择true就是倒过来的,比如当选择false的时候效果如左图,选择true效果如右图
V7包还有网格布局,参数的第二个表示几列,效果如下图,如果数据很多的话,可以上下拖动的。
rv.setLayoutManager(new GridLayoutManager(this,3));