Android-VLayout初尝试(使用体验下吧)

作者: MonkeyLei | 来源:发表于2019-07-21 16:51 被阅读0次

    阿里开源了一个Rv的多布局的替代方案alibaba/vlayout,简单用了下。总体感觉比较适合复杂多布局多嵌套的页面,像xx宝,xx东什么的那种,首页花里胡哨的一堆。(小萌新一直喜欢国外很多简约风格的以及高质量推送的那种,但是不是很花的那种,哈哈。。。)

    如果是简单的一些应用,像小萌新参与开发的新闻类(界面简洁清爽的那种), 工具类,学习教育类的那种。感觉可以自己多布局基本就能满足需求。 之前小萌新不是也尝试做了通用适配器的封装么MonkeyLei:Android-RecyclerView通用适配器BaseAdapter-多绘制类型-Base相关类,目前该通用适配器以及MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-初步封装-完善优化数据【对象】请求 以及运用到了新项目中,之前的有个工程已经重构完成,并经过测试。回头再琢磨琢磨看看!!!感觉还是不够呀。。其中有看过一个通用适配器的开源方案,小萌新的大体思路倒还蛮像的,哈哈!

    vlayout一直没用,现在想起要试试。一方面可能新的App(具体年后定)会有用到。另外就是也看了一些个培训机构,有涉及到这个。所以对于小萌新来说,还是值得试试的。我的试法就是快速体验,各种博客网站巴拉巴拉,没去仔细看官方了。 使用过程看看能不能体会个流程,机制啥的!

    走你...可以按照github上面的示例,注意的是MyAdapter的实现;另外可以下载官方demo来看,那样就妥了!

    主要分三步:

    1. 找到Rv,设置一个VirtualLayoutManager

            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
            VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
    
            recyclerView.setLayoutManager(layoutManager);
    

    2. 创建一个Adapter列表,并添加一个布局适配器,比如LinearLayoutAdapter

            //设置Adapter列表
            List<DelegateAdapter.Adapter> adapters = new LinkedList<>();
            ///< 线性布局
            LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();
            linearLayoutHelper.setMarginBottom(100);
            adapters.add(new LinearLayoutAdapter(this,linearLayoutHelper,2){
                @Override
                public void onBindViewHolder(MainViewHolder holder, int position) {
                    super.onBindViewHolder(holder, position);
                    if (position == 0) {
                        holder.tv1.setText("linearLayout1");
                    }
                }
            });
            ///< 再添加一个
            adapters.add(new LinearLayoutAdapter(this,linearLayoutHelper,2){
                @Override
                public void onBindViewHolder(MainViewHolder holder, int position) {
                    super.onBindViewHolder(holder, position);
                    if (position == 0) {
                        holder.tv1.setText("linearLayout2");
                    }
                }
            });
    

    3. 实现LinearLayoutAdapter

     package com.example.hl;
    
    import android.content.Context;
    import android.support.annotation.NonNull;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import com.alibaba.android.vlayout.DelegateAdapter;
    import com.alibaba.android.vlayout.LayoutHelper;
    import com.example.lieyun_android.myapplication.R;
    
    public class LinearLayoutAdapter extends DelegateAdapter.Adapter<LinearLayoutAdapter.MainViewHolder> {
        private Context context;
        private LayoutHelper layoutHelper;
        private RecyclerView.LayoutParams layoutParams;
        private int count = 0;
    
        public LinearLayoutAdapter(Context context, LayoutHelper layoutHelper, int count) {
            this(context, layoutHelper, count, new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300));
        }
    
        public LinearLayoutAdapter(Context context, LayoutHelper layoutHelper, int count, @NonNull RecyclerView.LayoutParams layoutParams) {
            this.context = context;
            this.layoutHelper = layoutHelper;
            this.count = count;
            this.layoutParams = layoutParams;
        }
    
        @Override
        public LayoutHelper onCreateLayoutHelper() {
            return layoutHelper;
        }
    
        @Override
        public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new MainViewHolder(LayoutInflater.from(context).inflate(R.layout.layout,parent,false));
        }
    
        @Override
        public void onBindViewHolder(MainViewHolder holder, int position) {
            holder.tv1.setText(Integer.toString(position));
        }
    
        @Override
        public int getItemCount() {
            return count;
        }
    
        static class MainViewHolder extends RecyclerView.ViewHolder {
            public TextView tv1;
            public MainViewHolder(View itemView) {
                super(itemView);
                tv1 = (TextView) itemView.findViewById(R.id.item_tv1);
            }
        }
    }
    
    

    布局文件laoyut.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/item_tv1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    
    

    基本上就可以啦..加几个Adaper就对应嵌套了几个布局,大概这个意思。

    image

    根据小萌新之前封装通用适配器的感受,其实就是多Adapter的LinkedList列表就相当于Rv多布局的类型,每个类型对应了一套View(也就是多个数量的Item被包装到了Adapter中)。小萌新的通用适配器是将类型type放到了List<Data>的每个Data中,根据type的分别进行不同布局的加载。

    如果需要多种不同类型的布局,就往List<DelegateAdapter.Adapter> adapters中添加即可。只要把不同类型的适配器Adapter准备好就行。

    image

    2. 比如再来个GridLayoutHelper类型的

            ///< 网格布局 - 构造中传入相应的列的数量
            GridLayoutHelper gridHelper = new GridLayoutHelper(5);
            gridHelper.setMarginTop(30);
            //gridHelper.setSpanCount(5);
            //设置垂直方向条目的间隔
            gridHelper.setVGap(5);
            //设置水平方向条目的间隔
            gridHelper.setHGap(5);
            gridHelper.setMarginLeft(30);
            gridHelper.setMarginRight(30);
            gridHelper.setMarginBottom(30);
            //自动填充满布局,在设置完权重,若没有占满,自动填充满布局
            gridHelper.setAutoExpand(true);
            adapters.add(new GridHelperAdapter(null, gridHelper));
    

    GridHelperAdapter.java

      package com.example.hl;
    
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    
    import com.alibaba.android.vlayout.DelegateAdapter;
    import com.alibaba.android.vlayout.LayoutHelper;
    import com.alibaba.android.vlayout.layout.GridLayoutHelper;
    import com.example.lieyun_android.myapplication.R;
    
    import java.util.List;
    
    public class GridHelperAdapter extends DelegateAdapter.Adapter<GridHelperAdapter.MainViewHolder>{
    
        private List<String> imgList;
        private GridLayoutHelper gridHelper;
    
        public GridHelperAdapter(List<String> imgList, GridLayoutHelper gridHelper){
            this.imgList = imgList;
            this.gridHelper = gridHelper;
        }
    
        @Override
        public LayoutHelper onCreateLayoutHelper() {
            return gridHelper;
        }
    
        @Override
        public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_grid_layout, parent, false);
            return new MainViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(MainViewHolder holder, int position) {
            holder.iv1.setBackgroundResource(R.drawable.aaa);
        }
    
        @Override
        public int getItemCount() {
            return 11;
        }
    
        static class MainViewHolder extends RecyclerView.ViewHolder {
            public ImageView iv1;
            public MainViewHolder(View itemView) {
                super(itemView);
                iv1 = (ImageView) itemView.findViewById(R.id.item_iv1);
            }
        }
    }
    
    

    item_grid_layout.xml

     <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    
        <ImageView
            android:id="@+id/item_iv1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    
    

    也就oK了

    image

    3. 然后像吸顶的StickyLayoutHelper也是类似做法,依葫芦画瓢,都差不多。

            List<String> mList = new ArrayList<>();
            mList.add("test");
            StickyLayoutHelper stickyHelper = new StickyLayoutHelper();
            adapters.add(new StickyLayoutAdapter(mList, stickyHelper));
    

    StickyLayoutAdapter.java

        package com.example.hl;
    
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    
    import com.alibaba.android.vlayout.DelegateAdapter;
    import com.alibaba.android.vlayout.LayoutHelper;
    import com.alibaba.android.vlayout.layout.StickyLayoutHelper;
    import com.example.lieyun_android.myapplication.R;
    
    import java.util.List;
    
    public class StickyLayoutAdapter extends DelegateAdapter.Adapter<StickyLayoutAdapter.MainViewHolder>{
    
        private List<String> imgList;
        private StickyLayoutHelper stickyLayoutHelper;
    
        public StickyLayoutAdapter(List<String> imgList, StickyLayoutHelper stickyLayoutHelper){
            this.imgList = imgList;
            this.stickyLayoutHelper = stickyLayoutHelper;
        }
    
        @Override
        public LayoutHelper onCreateLayoutHelper() {
            return stickyLayoutHelper;
        }
    
        @Override
        public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_stick_layout, parent, false);
            return new MainViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(MainViewHolder holder, int position) {
            holder.iv1.setBackgroundResource(R.drawable.aaa);
        }
    
        @Override
        public int getItemCount() {
            return imgList.size();
        }
    
        static class MainViewHolder extends RecyclerView.ViewHolder {
            public ImageView iv1;
            public MainViewHolder(View itemView) {
                super(itemView);
                iv1 = (ImageView) itemView.findViewById(R.id.item_iv1);
            }
        }
    }
    
    

    item_stick_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="20dp">
    
        <ImageView
            android:id="@+id/item_iv1"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
    
    

    差不多就是酱紫。重点是除了使用,我们要了解大概的原理。我们发现实现它的Adapter流程和我们之前普通的RecyclerView.Adapter差不多,不过阿里给做了一层包装,增加了额外的处理,可能重点区别就是:

        @Override
        public LayoutHelper onCreateLayoutHelper() {
            return stickyLayoutHelper;
        }
    

    1. 首先被调用地方 - 这就是代理Adapter的设置方式,将多个Adapter进行了存储,具体不跟了,后面再学习下。就是觉得多布局被它封装成了多个Adapter的方式(以往我们的多布局是一个Adapter,根据type加载不同布局,形成了一对多;阿里貌似给搞成了一对一,但是一个就包含N个条目,那它怎么实现的渲染,这个要看VirtualLayoutManager - 还是后续看看源码吧,我都胡说这么多了,不能再胡说了..):

    image image

    2. 此Adapter是:

    image

    简单过到这里,具体怎么渲染,还不懂,呵呵哒! 总归目标就是一个Rv实现多布局渲染,I Think!

    参考链接都给友情转发下:

    alibaba/vlayout

    vlayout--让你的多布局不再头疼

    阿里开源库VLayout的使用笔记 - totond的博客 - CSDN博客

    [Android]使用VLayout,你可能遇到的问题 - 嵌套横向滚动的Rv的参考

    相关文章

      网友评论

        本文标题:Android-VLayout初尝试(使用体验下吧)

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