美文网首页程序员
RecyclerView混合布局

RecyclerView混合布局

作者: 其实我很菜啊 | 来源:发表于2017-10-29 11:48 被阅读0次

    RecyclerView对于每一个学习安卓的人来说已不再陌生,RecyclerView的使用场景非常多例如多种样式的列表,宫格和列表同时存在,分类列表即新闻浏览、淘宝页面和通讯录。这些我们经常看到的布局都是有RecyclerView搭建起来的,所以这是一个非常强大的控件。

    RecyclerView实现多种布局的原理及机制

    (一)RecyclerView中的关键成员

    1. Type<-getItemViewType(int postion)
    2. Holder<-RecyclerView.Holder
    3. Recycler<-RecyclerView.Recycler(保存了一些缓存的机制)

    (二)Tyepe Hoder Recycler的作用

    getItemViewType
    1. ItemType保存在Holder中
    2. Holder根据postion保存在cache中,当我们需要复用时,从cache中取出holder
    3. 遍历缓存中的holder,如果Type一致就返回
    RecyclerView.Holder

    在RecyclerView中保存View的单位 记录RV中基本信息

    RecyclerView.Recycler

    RecyclerView中被存放的Holder 多个RV共用一个RecyclerPool(缓存池,一个静态的内部类) 配置size

    (二)多布局类型设计流程

    getItemViewType(offsetPosititon)->根据Type寻求Holder如果为空->adapter.createViewHolder否则->adapetr.bindViewHolder

    引入RecyclerView依赖库

    在工程build.grade中添加,只需将appcompat换成recyclerview即可

    dependencies {
        compile 'com.android.support:appcompat-v7:26.+'
        compile 'com.android.support:recyclerview-v7:26.+'
    }
    

    实现效果

    效果图.png

    可以看到布局中混合了三种样式

    实现代码

    创建一个自定义的RecyclerView适配器DemoAdapter

    public class DemoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        private Context mcontext;
    
        private LayoutInflater mLayoutInflater;
    
        private List<DataModle> mList=new ArrayList<>();
    
        public DemoAdapter(Context context) {
            mcontext=context;
            mLayoutInflater=LayoutInflater.from(mcontext);
        }
    
        public void addList( List<DataModle> List){
            mList.addAll(List);
        }
    
        /**
         *生成不同类型的布局
         */
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            switch (viewType){
                case DataModle.TYPE_ONE:
                    return new TypeOneViewHolder(mLayoutInflater.inflate(R.layout.item_type_one,parent,false));
                case DataModle.TYPE_TWO:
                    return new TypeTwoViewHolder(mLayoutInflater.inflate(R.layout.item_type_two,parent,false));
                case DataModle.TYPE_THREE:
                    return new TypeThreeViewHolder(mLayoutInflater.inflate(R.layout.item_type_three,parent,false));
            }
    
            return null;
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            //抽象出TypeAbstartViewHolder,所以在进行绑定的时候可以直接调用
            ((TypeAbstarctViewHolder)holder).bindHolder(mList.get(position));
        }
    
        @Override
        public int getItemViewType(int position) {
            return mList.get(position).type;
        }
    
        @Override
        public int getItemCount() {
            return mList.size();
        }
    }
    

    因为每次都会调用到onBindViewHolder进行对三种布局的参数设置,所以将TypeAbstartViewHolder抽象出来,它是继承RecyclerView.ViewHolder的。然后在创建三种布局各种的ViewHolder时直接继承该抽象类即可。

    public abstract class TypeAbstarctViewHolder extends RecyclerView.ViewHolder{
        public TypeAbstractViewHolder(View itemView) {
    
            super(itemView);
        }
        public abstract void bindHolder(DataModle modle);
    }
    

    现在只展示第三种布局的ViewHolder与布局文件,其他两种类型基本与此相同

    布局效果三.png
    public class TypeThreeViewHolder extends TypeAbstractViewHolder{
    
        public ImageView avatar;
    
        public ImageView contentImage;
    
        public TextView name;
    
        public TextView content;
    
        public TypeThreeViewHolder(View itemView){
            super(itemView);
    
            avatar=(ImageView)itemView.findViewById(R.id.avatar);
    
            contentImage=(ImageView)itemView.findViewById(R.id.contentImage);
    
            name=(TextView) itemView.findViewById(R.id.name);
    
            content=(TextView)itemView.findViewById(R.id.contennt);
        }
        @Override
        public void bindHolder(DataModle modle) {
            avatar.setBackgroundResource(modle.getAvatarColor());
            name.setText(modle.getName());
            content.setText(modle.getContent());
            contentImage.setBackgroundResource(modle.getContentColor());
        }
    }
    

    item_type_three.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        xmlns:tools="http://schemas.android.com/tools"
        android:background="@android:color/white"
        android:orientation="horizontal" >
    
        <ImageView
            android:layout_centerVertical="true"
            android:id="@+id/avatar"
            android:layout_marginLeft="20dp"
            android:layout_width="40dp"
            android:layout_height="40dp" />
    
        <LinearLayout
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/avatar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
    
            >
            <TextView
                android:id="@+id/name"
                tools:text="暗物质"
                android:layout_marginLeft="20dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <TextView
                android:id="@+id/contennt"
                tools:text="今天的天气很好"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="5dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
    
        </LinearLayout>
    
        <ImageView
    
            android:id="@+id/contentImage"
            android:layout_width="100dp"
            android:layout_height="45dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="20dp"
             />
    
    </RelativeLayout>
    

    最后MainActivity

    public class MainActivity extends AppCompatActivity {
    
        private RecyclerView mrecyclerview;
    
        private DemoAdapter mAdapter;
    
    
        int Colors[]={android.R.color.holo_blue_light,
                android.R.color.holo_red_light,android.R.color.holo_orange_light};
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mrecyclerview= (RecyclerView) findViewById(R.id.recyclerview);
            mrecyclerview.setLayoutManager(
                    new LinearLayoutManager(this,
                            LinearLayoutManager.VERTICAL,false));
            mAdapter=new DemoAdapter(this);
            mrecyclerview.setAdapter(mAdapter);
            
            //初始数据
            initData();
        }
    
        private void initData() {
            List<DataModle> dList=new ArrayList<>();
            for (int i=0;i<=20;i++){
                int type= (int) ((Math.random()*3)+1);//生成随机的Type
                DataModle data=new DataModle();
                data.setAvatarColor(Colors[type-1]);
                data.setType(type);
                data.setName("name :"+i);
                data.setContent("content :"+i);
                data.setContentColor(Colors[(type-1)%3]);
                dList.add(data);
            }
    
            mAdapter.addList(dList);
            mAdapter.notifyDataSetChanged();
        }
    
    }
    

    这是最简单的混合布局,接下来我将增加继续学习更多关于RecyclerView的混合布局,能实现RV悬浮效果就更好了。

    相关文章

      网友评论

        本文标题:RecyclerView混合布局

        本文链接:https://www.haomeiwen.com/subject/ykbjpxtx.html