在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表、应用列表、消息列表等等,但是从Android
一出生到现在并没有非常好用的列表控件,早期的 ListView
用法非常复杂,尤其是自定义列表,简直就是地狱,因为其中还涉及到很多效率优化的问题,新手很难写出高效率的基于列表应用,而且 ListView
只能垂直方向呈现内容,使用很不灵活,为了解决这个缺陷,Android 官方推出了 RecyclerView 控件,用来替代
ListView。
要使用Android RecyclerView,必须要添加它的库
具体用法写在注释里,其实和昨天那个FragmentAdapter的定义差不多
package com.jackie.courcerecv;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
recyclerView = new RecyclerView(this);
super.onCreate(savedInstanceState);
setContentView(recyclerView);
//为RecyclerView设置布局
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//为RecyclerView填充内容
recyclerView.setAdapter(new RecyclerView.Adapter(){
class MyViewHolder extends RecyclerView.ViewHolder{
//给子对象绑定类型为TextView,也可以自定义为图片或者其他
private TextView textView;
public MyViewHolder(TextView itemView) {
super(itemView);
textView = itemView;
}
public TextView getTextView() {
return textView;
}
}
//因为要返回一个ViewHolder,这里需要自定义一个ViewHolder
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//返回我们自己定义的MyViewHolder
return new MyViewHolder(new TextView(parent.getContext()));
}
//用position为特定位置的子对象赋值
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//获取到每一个MyViewHolder
TextView tv = ((MyViewHolder)holder).getTextView();
tv.setText("Item"+position);
}
//设置子对象个数为10
@Override
public int getItemCount() {
return 10;
}
});
}
}
通常情况下,列表试图的子对象都是通过数组来提供(无论是来源于数据库亦或是网络)。
String [] items = {"jackie","mary","moco"};
//获取到每一个MyViewHolder
TextView tv = ((MyViewHolder)holder).getTextView();
tv.setText("Item"+items[position]);
在安卓开发里面,直接用代码区写控件布局之类的,其实违背了软件的设计原则,耦合性太高,应该尽量使用资源文件来修改配置,这个资源文件其实就是一个布局的模板,里面可以放一些组件,图片啥的。
创建一个item.xml来规范列表项,每一个子对象里面
为了更好的看清楚结构,我们把之前的内部类Adapter转移成单独的类
Refactor-Move
然后把之前修改的子对象的TextView恢复到View
由于是从资源文件创建视图所以之前的
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//返回我们自己定义的MyViewHolder
return new MyViewHolder(new View(parent.getContext()));
}
要修改为
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//返回我们自己定义的MyViewHolder
return new MyViewHolder(LayoutInflater
.from(parent.getContext())
.inflate(R.layout.list_item, null));
}
由于我给每个子对象布局里面设置了标题、内容、按钮,所以在ViewHolder构造方法里,可以找到这些控件
。。。好吧其实这个ViewHolder就是装载子对象的一个容器,子对象里有什么它里面就有什么,然后可以定义一个实体类用来存放标题和内容,比如叫Cell,里面三个成员变量分别是之前布局里的标题、内容和按钮;
package com.jackie.courcerecv;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
recyclerView = new RecyclerView(this);
super.onCreate(savedInstanceState);
setContentView(recyclerView);
//为RecyclerView设置布局
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//为RecyclerView填充内容
recyclerView.setAdapter(new MyAdapter());
}
}
package com.jackie.courcerecv;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* Created by Law on 2015/10/29.
*/
class MyViewHolder extends RecyclerView.ViewHolder {
private View root;
private TextView tvTitle;
private TextView tvContent;
private Button btnOk;
public MyViewHolder(View itemView) {
super(itemView);
root = itemView;
tvTitle = (TextView) root.findViewById(R.id.tvTitle);
tvContent = (TextView) root.findViewById(R.id.tvContent);
btnOk = (Button) root.findViewById(R.id.btnOk);
}
public View getView() {
return root;
}
public TextView getTvTitle() {
return tvTitle;
}
public TextView getTvContent() {
return tvContent;
}
public Button getBtnOk() {
return btnOk;
}
}
package com.jackie.courcerecv;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by Law on 2015/10/29.
*/
class MyAdapter extends RecyclerView.Adapter {
//因为要返回一个ViewHolder,这里需要自定义一个ViewHolder
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//返回我们自己定义的MyViewHolder
return new MyViewHolder(LayoutInflater
.from(parent.getContext())
.inflate(R.layout.list_item, null));
}
//用position为特定位置的子对象赋值
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Cell cell1=new Cell("Item1","This is item1");
Cell cell2=new Cell("Item2","This is item2");
Cell cell3=new Cell("Item3","This is item3");
Cell []cells ={cell1,cell2,cell3};
//获取到每一个MyViewHolder
TextView tvTitle = ((MyViewHolder) holder).getTvTitle();
tvTitle.setText(cells[position].getTitle());
TextView tvContent = ((MyViewHolder) holder).getTvContent();
tvContent.setText(cells[position].getContent());
}
//设置子对象个数为10
@Override
public int getItemCount() {
return 3;
}
}
可以看到效果是垂直的,也可以变成水平的,在哪里设置呢?是在
MainActivity里面
recyclerView.setLayoutManager(new LinearLayoutManager(this));
修改一下:
recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));
同样的方法还可以修改更多的样式。