android开发之recycleView的使用

一、recycleView的使用场景

1、多种样式的列表
2、宫格和列表同时存在
3、分类列表比如通讯录城市列表等

二、基本使用

在布局文件中声明
在Activity中使用
Adapter的创建
添加单击事件
Item动画
更新数据

1、在布局文件中声明


 

2、在Activity中使用

复制代码
// 1,找到这个View
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
// 2,设置布局管理LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// 3,(可选)如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
mRecyclerView.setHasFixedSize(true);
// 4,设置Adapter
mRecyclerView.setAdapter(new MyAdapter());
复制代码
 

目前SDK中提供了三种自带的LayoutManager:

LinearLayoutManager

GridLayoutManager

StaggeredGridLayoutManager

LinearLayoutManager

mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
GridLayoutManager

mLayoutManager = new GridLayoutManager(context,columNum);
mRecyclerView.setLayoutManager(mLayoutManager);
注:在Grid布局中也可以设置列表的Orientation属性,来实现横向和纵向的Grid布局。

StaggeredGridLayoutManager

瀑布流就使用StaggeredGridLayoutManager吧,具体使用方法见http://blog.csdn.net/duanymin/article/details/44979355

 

3、Adapter的创建

复制代码
 1 public class MyAdapter extends RecyclerView.Adapter {
 2     public String[] datas = null;
 3     public MyAdapter(String[] datas) {
 4         this.datas = datas;
 5     }
 6     //创建新View,被LayoutManager所调用
 7     @Override
 8     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
 9         View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);
10         ViewHolder vh = new ViewHolder(view);
11         return vh;
12     }
13     //将数据与界面进行绑定的操作
14     @Override
15     public void onBindViewHolder(ViewHolder viewHolder, int position) {
16         viewHolder.mTextView.setText(datas[position]);
17     }
18     //获取数据的数量
19     @Override
20     public int getItemCount() {
21         return datas.length;
22     }
23     //自定义的ViewHolder,持有每个Item的的所有界面元素
24     public static class ViewHolder extends RecyclerView.ViewHolder {
25         public TextView mTextView;
26         public ViewHolder(View view){
27         super(view);
28             mTextView = (TextView) view.findViewById(R.id.text);
29         }
30     }
31 }
复制代码
 

4、添加单击事件

复制代码
// 1 定义接口
public static interface OnRecyclerViewItemClickListener {
    void onItemClick(View view , DataModel data);
}

// 2 添加接口和设置接口的方法
private OnRecyclerViewItemClickListener mOnItemClickListener = null;
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
    this.mOnItemClickListener = listener;
}

// 3 在Adapter实现OnClickListener方法
public class MyAdapter extends RecyclerView.Adapter implements View.OnClickListener{
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        ViewHolder vh = new ViewHolder(view);
        //将创建的View注册点击事件
        view.setOnClickListener(this);
        return vh;
    }
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int i) {
        viewHolder.mTextView.setText(datas.get(i).title);
        //将数据保存在itemView的Tag中,以便点击时进行获取
        viewHolder.itemView.setTag(datas.get(i));
    }
    ...
    @Override
    public void onClick(View v) {
        if (mOnItemClickListener != null) {
            //注意这里使用getTag方法获取数据

        }
    ...
}
复制代码
在Activity中

复制代码
mAdapter = new MyAdapter(getDummyDatas());
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new MyAdapter.OnRecyclerViewItemClickListener() {
    @Override
    public void onItemClick(View view, DataModel data) {
        //DO your fucking bussiness here!
    }
});
复制代码
 

5、Item动画

// 设置item动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
如果要自定义动画效果需要继承ItemAnimator

GitHub上的动画效果:RecyclerViewItemAnimators

 

6、更新数据

这里更新数据集不是用adapter.notifyDataSetChanged()而是 notifyItemInserted(position)与notifyItemRemoved(position) 否则没有动画效果。 

为adapter中添加两个方法:

复制代码
public void addData(int position) {
    mDatas.add(position, "Insert One");
    notifyItemInserted(position);
}

public void removeData(int position) {
    mDatas.remove(position);
    notifyItemRemoved(position);
}

三、复杂布局的实现逻辑

1、RecycleView的关键成员

  A、Type:类型 通过getItemViewType(position)获取
  B、Holder(熟悉ListView的都知道)
        1、holder在recycleView中保存view的单位
        2、记录recycleview中的基本信息
  C、RecycleView.Recycler(保存了一些缓存机制)
         1、Recycleview中被缓存的holder
         2、多个RecycleView共用一个RecycleredPool(缓存池)
         3、配置缓存size

2、getItemViewType

 a、ItemType保存在Holder中
 B、Holder根据position被缓存在cache中
 RecycleView之所以流畅,就是当我们需要复用的时候系统会在cache中拿holder,进而实现使用流畅。
 C、遍历缓存中的holder,如果Type一致就返回。  

3、多布局的实现

 A、复写getItemViewType方法
 B、需要处理getItemCount方法
 C、按照获取的Type处理onCreateViewHolder和OnBinderViewHolder。

4、数据的处理

 A、把多个数据类型都包装进一个Object(不利于查找)
 B、封装RecycleView.Adapter,把一些不同的item当做header添加进来

5、多布局类型运行流程

滚动布局——》通过getItemViewType获取Type类型——》根据类型寻找holder——》如果holder为null执行adapter.createrHolder,否则执行adapter.bindViewHolder.

四、通过LinearLayoutManager实现多布局代码:

 recyclerView = (RecyclerView) findViewById(R.id.recycleview);
        recyclerView.setLayoutManager(new LinearLayoutManager(this,
                LinearLayoutManager.VERTICAL,false));
        adapter = new MyRecyclerViewAdapter(this);
        recyclerView.setAdapter(adapter);
        initData();

/**
* 模拟数据
/
private void initData(){
List dataBeanList = new ArrayList<>();
for(int i=0;i<20;i++){
int type = (int) ((Math.random()
3)+1);
DataBean dataBean = new DataBean();
dataBean.titelColor = typeColors[type-1];
dataBean.type = type;
dataBean.contentColor = typeColors[(type+1)%3];
dataBean.content = "content"+i;
dataBean.name = "name"+i;
dataBeanList.add(dataBean);
}
adapter.addData(dataBeanList);
}

}

多布局就是不同的Viewholder加载渲染不同的布局,通过Type进行区分。
布局一和所对应的viewHolder、



    

    



/**
 * 布局一viewholder
 * Created by zzj on 2017/2/16.
 */

public class TypeOneHolder extends TypeAbstractHolder {
    private ImageView titel_image;
    private TextView name_tv;
    public TypeOneHolder(View itemView) {
        super(itemView);
        titel_image = (ImageView) itemView.findViewById(R.id.title_image);
        name_tv = (TextView) itemView.findViewById(R.id.name_tv);
    }

    @Override
    public void onBindData(DataBean dataBean) {
        titel_image.setImageResource(dataBean.titelColor);
        name_tv.setText(dataBean.name);
    }
}

布局二、



    


    
        
        
    



/**布局二viewholder
 * Created by zzj on 2017/2/16.
 */

public class TypeTwoHolder extends TypeAbstractHolder {
    private ImageView titel_image;
    private TextView name_tv,content_tv;
    public TypeTwoHolder(View itemView) {
        super(itemView);
        titel_image = (ImageView) itemView.findViewById(R.id.title_image);
        name_tv = (TextView) itemView.findViewById(R.id.name_tv);
        content_tv = (TextView) itemView.findViewById(R.id.content_tv);

    }

    @Override
    public void onBindData(DataBean dataBean) {
        titel_image.setImageResource(dataBean.titelColor);
        name_tv.setText(dataBean.name);
        content_tv.setText(dataBean.content);
    }
}

布局三、



    


    
        
        
    

    



/**布局三viewholder
 * Created by zzj on 2017/2/16.
 */

public class TypeThreeHolder extends TypeAbstractHolder {
    private ImageView titel_image,content_image;
    private TextView name_tv,content_tv;
    public TypeThreeHolder(View itemView) {
        super(itemView);
        titel_image = (ImageView) itemView.findViewById(R.id.title_image);
        name_tv = (TextView) itemView.findViewById(R.id.name_tv);
        content_tv = (TextView) itemView.findViewById(R.id.content_tv);
        content_image = (ImageView) itemView.findViewById(R.id.content_image);
    }

    @Override
    public void onBindData(DataBean dataBean) {
        titel_image.setImageResource(dataBean.titelColor);
        name_tv.setText(dataBean.name);
        content_tv.setText(dataBean.content);
        content_image.setImageResource(dataBean.contentColor);
    }
}

ViewHolder的父类

public abstract class TypeAbstractHolder extends RecyclerView.ViewHolder {

    public TypeAbstractHolder(View itemView) {
        super(itemView);
    }

    /**
     * 绑定数据
     * @param dataBean
     */
    public abstract void onBindData(DataBean dataBean);
}

在Adapter中创建绑定ViewHolder


      @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case DataBean.TYPE_ONE:
                return new TypeOneHolder(inflater.inflate(R.layout.item_recycleview_linear_type_one,parent,false));
            case DataBean.TYPE_TWO:
                return new TypeTwoHolder(inflater.inflate(R.layout.item_recycleview_linear_type_two,parent,false));
            case DataBean.TYPE_THREE:
                return new TypeThreeHolder(inflater.inflate(R.layout.item_recycleview_linear_type_three,parent,false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        ((TypeAbstractHolder)holder).onBindData(dataBeanList.get(position));
    }

由上而下的多布局就基本创建完成。

你可能感兴趣的:(android开发之recycleView的使用)