Android 5.0推出的同时,Google工程师在support-v7包下引入了一个全新的列表控件RecyclerView,这个控件比ListView和GridView都灵活,可用于显示庞大的数据。
三要素:adapter,LayoutManager ,数据源
下面是一个简单的示例代码:
activity_main.xml
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List datas = new ArrayList<>();
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
initDatas();
//创建流式布局
StaggeredGridLayoutManager gridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
assert recyclerView != null;
recyclerView.setLayoutManager(gridLayoutManager);
//如果item的高度固定,这样写提高效率
recyclerView.setHasFixedSize(true);
//创建并设置adapter
MyAdapter myAdapter = new MyAdapter(datas);
recyclerView.setAdapter(myAdapter);
}
public void initDatas(){
datas.add( "美国");
datas.add("比利时");
datas.add("巴西");
datas.add("意大利");
datas.add( "葡萄牙");
datas.add("西班牙");
datas.add("克罗地亚");
}
}
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter {
public List datas = null;
public MyAdapter(List datas){
this.datas = datas;
}
//创建新view被layoutManager所调用
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.item,parent,false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
//将数据与界面进行绑定
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.textView.setText(datas.get(position));
}
//获取数据的数量
@Override
public int getItemCount() {
return datas.size();
}
//自定义的ViewHolder,持有每个item的所有界面元素
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView textView;
public ViewHolder(View view){
super(view);
textView = (TextView) view.findViewById(R.id.text);
}
}
}
item.xml
不同布局应用示例:
为RecyclerView添加点击事件:
1.首先在Adaper文件中创建一个实现点击的接口,其中view是点击的item,data是数据,position是条目的位置,有了这些参数就可以定义下步操作了。
public static interface OnRecyclerViewItemClickListener{
void onItemClick(View view,String data,int position);
}
2.定义完接口,在Adapter中添加接口和添加设置接口的方法:
private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener = null;
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener){
this.onRecyclerViewItemClickListener = listener;
}
3.接口在Adapter中具体如何使用,如下所示:
public class MyAdapter extends RecyclerView.Adapter implements View.OnClickListener{
public List datas = null;
public MyAdapter(List datas){
this.datas = datas;
}
private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener = null;
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener){
this.onRecyclerViewItemClickListener = listener;
}
//创建新view被layoutManager所调用
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.item,parent,false);
ViewHolder vh = new ViewHolder(view);
view.setOnClickListener(this);
return vh;
}
//将数据与界面进行绑定
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.textView.setText(datas.get(position));
viewHolder.itemView.setTag(position);
}
//获取数据的数量
@Override
public int getItemCount() {
return datas.size();
}
//自定义的ViewHolder,持有每个item的所有界面元素
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView textView;
public ViewHolder(View view){
super(view);
textView = (TextView) view.findViewById(R.id.text);
}
}
public static interface OnRecyclerViewItemClickListener{
void onItemClick(View view,String data,int position);
}
@Override
public void onClick(View view) {
if (onRecyclerViewItemClickListener != null){
int position = (int) view.getTag();
onRecyclerViewItemClickListener.onItemClick(view,datas.get(position),position);
}
}
}
4.做完这些就可以在MainActivity中添加点击事件了,具体如下:
MyAdapter myAdapter = new MyAdapter(datas);
recyclerView.setAdapter(myAdapter);
myAdapter.setOnItemClickListener(new MyAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View view, String data, int position) {
Toast.makeText(getApplicationContext(),data,Toast.LENGTH_SHORT).show();
}
});
5.RecyclerView中添加删除数据
liseview中增删数据的方法这里也有,但是这边还有更高级的,可以自带动画的删除或者增加条目。可以在MyAdapter中创建如下方法:
public void addItem(String content,int position){
datas.add(position,content);
notifyItemInserted(position);
}
public void removeItem(String content,int position){
datas.remove(content);
notifyItemRemoved(position);
}
注意这里更新数据集不用adapter.notifyDataSetChanged(),否则无动画效果。
还可以增加常用的下拉刷新功能,把要实现下拉刷新功能的控件放置到SwipRefreshLayout=中,就能让这个控件支持下拉刷新。下面是使用的示例:
activity_main.xml文件:
MainActivity.java文件
public class MainActivity extends AppCompatActivity {
List datas = new ArrayList<>();
SwipeRefreshLayout swipeRefresh;
MyAdapter myAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//下拉刷新
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefresh.setColorSchemeResources(R.color.colorPrimary); //设置刷新进度条颜色
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//处理刷新逻辑
refresh();
}
});
}
//模拟网络交互
private void refresh(){
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
}catch (InterruptedException e){
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
myAdapter.notifyDataSetChanged(); //通知数据变化
swipeRefresh.setRefreshing(false); //停止刷新
}
});
}
}).start();
}
//...
}