VLayout使用-手寫淘寶主界面

VLayout描述

VirtualLayout是一個針對RecyclerView的LayoutManager擴(kuò)展, 主要提供一整套布局方案和布局間的組件復(fù)用的問題装畅。
vlayout全稱VirtualLayout伍伤,它是一個針對RecyclerView的LayoutManager擴(kuò)展, 主要提供一整套布局方案和布局間的組件復(fù)用的問題。
它通過定制化的LayoutManager暗赶,接管整個RecyclerView的布局邏輯;LayoutManager管理了一系列LayoutHelper肃叶,
LayoutHelper負(fù)責(zé)具體布局邏輯實(shí)現(xiàn)的地方蹂随;每一個LayoutHelper負(fù)責(zé)頁面某一個范圍內(nèi)的組件布局;不同的LayoutHelper可以做不同的布局邏輯因惭,
因此可以在一個RecyclerView頁面里提供異構(gòu)的布局結(jié)構(gòu)岳锁,這就能比系統(tǒng)自帶的LinearLayoutManager、GridLayoutManager等提供更加豐富的能力蹦魔。同時支持?jǐn)U展LayoutHelper來提供更多的布局能力激率。

場景使用模式(電商項(xiàng)目用的最多)

原生開發(fā) 短處就是復(fù)雜界面的開發(fā)非常麻煩 要解決事件分發(fā)以及滾動控件的嵌套問題
默認(rèn)通用布局實(shí)現(xiàn),解耦所有的View和布局之間的關(guān)系: Linear, Grid, 吸頂, 浮動, 固定位置等
1:LinearLayoutHelper: 線性布局
2:GridLayoutHelper: Grid布局勿决, 支持橫向的colspan
3:FixLayoutHelper: 固定布局乒躺,始終在屏幕固定位置顯示
4:ScrollFixLayoutHelper: 固定布局,但之后當(dāng)頁面滑動到該圖片區(qū)域才顯示, 可以用來做返回頂部或其他書簽等
5:FloatLayoutHelper: 浮動布局低缩,可以固定顯示在屏幕上嘉冒,但用戶可以拖拽其位置
6:ColumnLayoutHelper: 欄格布局,都布局在一排,可以配置不同列之間的寬度比值
7:SingleLayoutHelper: 通欄布局讳推,只會顯示一個組件View
8:OnePlusNLayoutHelper: 一拖N布局顶籽,可以配置1-5個子元素
9:StickyLayoutHelper: stikcy布局, 可以配置吸頂或者吸底
10:StaggeredGridLayoutHelper: 瀑布流布局娜遵,可配置間隔高度/寬度

上述默認(rèn)實(shí)現(xiàn)里可以大致分為兩類:一是非fix類型布局蜕衡,像線性、Grid设拟、欄格等慨仿,它們的特點(diǎn)是布局在整個頁面流里,隨頁面滾動而滾動纳胧;另一類就是fix類型的布局镰吆,它們的子節(jié)點(diǎn)往往不隨頁面滾動而滾動。
所有除布局外的組件復(fù)用跑慕,VirtualLayout將用來管理大的模塊布局組合万皿,擴(kuò)展了RecyclerView,使得同一RecyclerView內(nèi)的組件可以復(fù)用核行,減少View的創(chuàng)建和銷毀過程牢硅。

使用VLayout

1.添加依賴包
implementation 'com.alibaba.android:vlayout:1.0.3@aar'
implementation 'com.android.support:recyclerview-v7:28.0.0-beta01'

排版并不是把所有元素隨意丟到界面顯示,它需要符合人類的審美觀芝雪,這個無論是Android還是Web等都是通用的
排版是一種界面的整齊劃分减余,符合用戶的審美需求,常用排版有以下幾種:
有時候我們判斷某個APP到底是用H5做的還是用原生做的惩系,只需要打開開發(fā)者模式里面的顯示布局邊界位岔,就能看到里面的嵌套從而判斷是不是原生。


image.png
image.png
常用的排版

LinearLayoutHelper——線性布局
GridLayoutHelper Grid布局
ScrollFixLayoutHelper——固定布局
ColumnLayoutHelper——欄格布局
FloatLayoutHelper——浮動布局
SingleLayoutHelper—— 一個元素布局
OnePlusNLayoutHelper——一拖N布局
StickyLayoutHelper——stikcy布局
StaggeredGridLayoutHelper——瀑布流布局

案例一(用法)
public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    //數(shù)據(jù)源
    private ArrayList<HashMap<String, Object>> listItem;
    //適配器
    private MyAdapter linearLayoutAdapter,stickyLayoutAdapter,gridLayoutAdapter,scrollFixLayoutAdapter,columnLayoutAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        recyclerView = findViewById(R.id.my_recycler_view);
        //以前的做法
        //recyclerView.setLayoutManager(new LinearLayoutManager());
        //VLayout對LayoutManager的封裝
        VirtualLayoutManager virtualLayoutManager = new VirtualLayoutManager(this);
        recyclerView.setLayoutManager(virtualLayoutManager);
        //給recyclerView設(shè)置回收池
        RecyclerView.RecycledViewPool recycledViewPool = new RecyclerView.RecycledViewPool();
        recyclerView.setRecycledViewPool(recycledViewPool);
        //設(shè)置recyclerView的item類型 以及最大item類型數(shù)量
        recycledViewPool.setMaxRecycledViews(0,10);


        // 線性布局----------------------------------->
        LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();
        //設(shè)置數(shù)據(jù)的總行數(shù)
        linearLayoutHelper.setItemCount(4);
        //其實(shí)這個就是設(shè)置itemView的padding值 它不等同于RecyclerView的padding值
        linearLayoutHelper.setPadding(20,20,20,20);
        linearLayoutHelper.setMargin(20,20,20,20);
        //設(shè)置寬高比  就是itemView的寬度和高度的比例 比如寬度是6   那么高度就是1
        linearLayoutHelper.setAspectRatio(6);
        //設(shè)置分割線高度
        linearLayoutHelper.setDividerHeight(10);
        //設(shè)置下邊距
        linearLayoutHelper.setMarginBottom(10);
        linearLayoutAdapter = new MyAdapter(this,linearLayoutHelper,20,listItem);


        //組合 --->順序
        //創(chuàng)建一個適配器的集合
        List<DelegateAdapter.Adapter> adapters = new LinkedList<>();
        adapters.add(linearLayoutAdapter);
        DelegateAdapter delegateAdapter = new DelegateAdapter(virtualLayoutManager);
        delegateAdapter.setAdapters(adapters);


        // 定格布局----------------------------------->
        StickyLayoutHelper stickyLayoutHelper = new StickyLayoutHelper();
        //設(shè)置數(shù)據(jù)的總行數(shù)
        stickyLayoutHelper.setItemCount(1);
        //設(shè)置寬高比  就是itemView的寬度和高度的比例 比如寬度是6   那么高度就是1
        stickyLayoutHelper.setAspectRatio(3);
        //定格布局的控件是在頂部還是在底部  true為頭部  false為底部
        stickyLayoutHelper.setStickyStart(true);
        //設(shè)置偏移值
        //stickyLayoutHelper.setOffset(100);
        stickyLayoutAdapter = new MyAdapter(this,stickyLayoutHelper,1,listItem){
            @Override
            public void onBindViewHolder(@NonNull MainViewHolder viewHolder, int position) {
                super.onBindViewHolder(viewHolder, position);
                if(position == 0){
                    viewHolder.Text.setText("Stick");
                }
            }
        };
        delegateAdapter.addAdapter(stickyLayoutAdapter);
        delegateAdapter.addAdapter(linearLayoutAdapter);



        //--------------網(wǎng)格布局-------------------->
        GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(4);
        gridLayoutHelper.setAspectRatio(6);
        //設(shè)置權(quán)重 就是一行中多個控件的比例  注意 加起來要等于100
        gridLayoutHelper.setWeights(new float[]{30,20,30,20});
        //設(shè)置垂直邊距
        gridLayoutHelper.setVGap(20);
        //設(shè)置水平邊距
        gridLayoutHelper.setHGap(20);
        //設(shè)置是否自動填充空白區(qū)域
        gridLayoutHelper.setAutoExpand(true);
        gridLayoutAdapter = new MyAdapter(this,gridLayoutHelper,20,listItem){
            @Override
            public void onBindViewHolder(@NonNull MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                //為了展示效果 將布局的不同位置的item進(jìn)行背景顏色設(shè)置
                if(position<2){
                    holder.itemView.setBackgroundColor(0x66cc0000 + (position-6)*128);
                }else if(position%2 == 0){
                    holder.itemView.setBackgroundColor(0xaa22ff22);
                }else{
                    holder.itemView.setBackgroundColor(0xccff22ff);
                }
                if(position == 0){
                    holder.Text.setText("Grid");
                }
            }
        };
        delegateAdapter.addAdapter(gridLayoutAdapter);



        //-----------------固定布局------------------>
        //第一個參數(shù) 是固定的位置  后面兩個參數(shù)是固定之后的偏移量
        ScrollFixLayoutHelper scrollFixLayoutHelper = new ScrollFixLayoutHelper(ScrollFixLayoutHelper.BOTTOM_RIGHT,10,10);
        // 參數(shù)說明:
        // 公共屬性
        // 設(shè)置布局里Item個數(shù)
        scrollFixLayoutHelper.setItemCount(1);
        // 設(shè)置LayoutHelper的子元素相對LayoutHelper邊緣的距離
        scrollFixLayoutHelper.setPadding(20, 20, 20, 20);
        // 設(shè)置LayoutHelper邊緣相對父控件(即RecyclerView)的距離
        scrollFixLayoutHelper.setMargin(20, 20, 20, 20);
        scrollFixLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        scrollFixLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比
        //重要參數(shù)  顯示類型   一直顯示SHOW_ALWAYS  滑動到位置開始位置顯示SHOW_ON_ENTER  滑動到結(jié)束位置顯示SHOW_ON_LEAVE 后面啷個參數(shù)一開始是不顯示的
        scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ALWAYS);
        scrollFixLayoutAdapter = new MyAdapter(this, scrollFixLayoutHelper,1, listItem) {
            // 設(shè)置需要展示的數(shù)據(jù)總數(shù),此處設(shè)置是1
            // 為了展示效果,通過重寫onBindViewHolder()將布局的第一個數(shù)據(jù)設(shè)置為scrollFix
            @Override
            public void onBindViewHolder(MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                if (position == 0) {
                    holder.Text.setText("scrollFix");
                }
            }
        };
        delegateAdapter.addAdapter(scrollFixLayoutAdapter);


        //柵格欄布局------------------------------->
        ColumnLayoutHelper columnLayoutHelper = new ColumnLayoutHelper();
        // 公共屬性
        // 設(shè)置LayoutHelper的子元素相對LayoutHelper邊緣的距離
        columnLayoutHelper.setPadding(20, 20, 20, 20);
        // 設(shè)置LayoutHelper邊緣相對父控件(即RecyclerView)的距離
        columnLayoutHelper.setMargin(20, 20, 20, 20);
        // 設(shè)置背景顏色
        columnLayoutHelper.setBgColor(Color.GRAY);
        // 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比
        columnLayoutHelper.setAspectRatio(6);
        // columnLayoutHelper特有屬性  設(shè)置該行每個Item占該行總寬度的比例
        columnLayoutHelper.setWeights(new float[]{30, 30,10, 30});
        columnLayoutAdapter = new MyAdapter(this, columnLayoutHelper,4, listItem) {
            // 設(shè)置需要展示的數(shù)據(jù)總數(shù),此處設(shè)置是3
            // 為了展示效果,通過重寫onBindViewHolder()將布局的第一個數(shù)據(jù)設(shè)置為Column
            @Override
            public void onBindViewHolder(MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                if (position == 0) {
                    holder.Text.setText("Column");
                    holder.itemView.setBackgroundColor(Color.RED);
                }else if(position == 1){
                    holder.itemView.setBackgroundColor(Color.YELLOW);
                }else{
                    holder.itemView.setBackgroundColor(Color.BLUE);
                }
            }
        };
        delegateAdapter.addAdapter(columnLayoutAdapter);


        //一盒元素布局 一個元素布局------------------------------>
        SingleLayoutHelper singleLayoutHelper = new SingleLayoutHelper();
        // 公共屬性
        // 設(shè)置LayoutHelper的子元素相對LayoutHelper邊緣的距離
        singleLayoutHelper.setPadding(20, 20, 20, 20);
        // 設(shè)置LayoutHelper邊緣相對父控件(即RecyclerView)的距離
        singleLayoutHelper.setMargin(20, 20, 20, 20);
        // 設(shè)置背景顏色
        singleLayoutHelper.setBgColor(Color.GRAY);
        // 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比
        singleLayoutHelper.setAspectRatio(6);
        MyAdapter singleLayoutAdapter = new MyAdapter(this, singleLayoutHelper,1, listItem) {
            // 設(shè)置需要展示的數(shù)據(jù)總數(shù),此處設(shè)置是1
            // 為了展示效果,通過重寫onBindViewHolder()將布局的第一個數(shù)據(jù)設(shè)置為Single
            @Override
            public void onBindViewHolder(MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                if (position == 0) {
                    holder.Text.setText("Single");
                }
            }
        };
        delegateAdapter.addAdapter(singleLayoutAdapter);


        //1拖N布局------------------------------->
        OnePlusNLayoutHelper onePlusNLayoutHelper = new OnePlusNLayoutHelper();
        //設(shè)置行比重
        onePlusNLayoutHelper.setColWeights(new float[]{40,60,30,30});
        //設(shè)置高比重
        onePlusNLayoutHelper.setRowWeight(60);
        // 設(shè)置LayoutHelper的子元素相對LayoutHelper邊緣的距離
        onePlusNLayoutHelper.setPadding(20, 20, 20, 20);
        // 設(shè)置LayoutHelper邊緣相對父控件(即RecyclerView)的距離
        onePlusNLayoutHelper.setMargin(20, 20, 20, 20);
        // 設(shè)置背景顏色
        onePlusNLayoutHelper.setBgColor(Color.GRAY);
        // 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比
        onePlusNLayoutHelper.setAspectRatio(3);
        MyAdapter onePlusNLayoutAdapter = new MyAdapter(this, onePlusNLayoutHelper,4, listItem) {
            // 設(shè)置需要展示的數(shù)據(jù)總數(shù),此處設(shè)置是5,即1拖4
            // 為了展示效果,通過重寫onBindViewHolder()將布局的第一個數(shù)據(jù)設(shè)置為onePlus
            @Override
            public void onBindViewHolder(MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                if (position == 0) {
                    holder.Text.setText("onePlus"+position);
                    holder.itemView.setBackgroundColor(Color.RED);
                }else if (position == 1) {
                    holder.Text.setText("onePlus"+position);
                    holder.itemView.setBackgroundColor(Color.BLUE);
                }else if (position == 2) {
                    holder.Text.setText("onePlus"+position);
                    holder.itemView.setBackgroundColor(Color.BLACK);
                }else if (position == 3) {
                    holder.Text.setText("onePlus"+position);
                    holder.itemView.setBackgroundColor(Color.GREEN);
                }
            }
        };

        delegateAdapter.addAdapter(onePlusNLayoutAdapter);



        //瀑布流布局------------------------------------------------------->
        StaggeredGridLayoutHelper staggeredGridLayoutHelper = new StaggeredGridLayoutHelper();
        // 公有屬性
        staggeredGridLayoutHelper.setItemCount(20);// 設(shè)置布局里Item個數(shù)
        staggeredGridLayoutHelper.setPadding(20, 20, 20, 20);
        staggeredGridLayoutHelper.setMargin(20, 20, 20, 20);
        staggeredGridLayoutHelper.setBgColor(Color.GRAY);
        staggeredGridLayoutHelper.setAspectRatio(3);
        // 特有屬性
        // 設(shè)置控制瀑布流每行的Item數(shù)
        staggeredGridLayoutHelper.setLane(3);
        // 設(shè)置子元素之間的水平間距
        staggeredGridLayoutHelper.setHGap(20);
        // 設(shè)置子元素之間的垂直間距
        staggeredGridLayoutHelper.setVGap(15);
        MyAdapter staggeredGridLayoutAdapter = new MyAdapter(this, staggeredGridLayoutHelper,20, listItem) {
            // 設(shè)置需要展示的數(shù)據(jù)總數(shù),此處設(shè)置是20
            // 通過重寫onBindViewHolder()設(shè)置更加豐富的布局
            @Override
            public void onBindViewHolder(MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,150 +position % 5 * 20);
                holder.itemView.setLayoutParams(layoutParams);
                // 為了展示效果,設(shè)置不同位置的背景色
                if (position > 10) {
                    holder.itemView.setBackgroundColor(0x66cc0000 );
                } else if (position % 2 == 0) {
                    holder.itemView.setBackgroundColor(0xaa22ff22);
                } else {
                    holder.itemView.setBackgroundColor(0xccff22ff);
                }
                // 為了展示效果,通過將布局的第一個數(shù)據(jù)設(shè)置為staggeredGrid
                if (position == 0) {
                    holder.Text.setText("staggeredGrid");
                }
            }
        };

        delegateAdapter.addAdapter(staggeredGridLayoutAdapter);

        recyclerView.setAdapter(delegateAdapter);

    }


    /**
     * 初始化數(shù)據(jù)
     */
    private void initData() {
        /**
         * 步驟1設(shè)置需要存放的數(shù)據(jù)
         * */
        listItem = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < 100; i++) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("ItemTitle", "第" + i + "行");
            map.put("ItemImage", R.mipmap.ic_launcher);
            listItem.add(map);

        }
    }
}
public class MyAdapter extends DelegateAdapter.Adapter<MyAdapter.MainViewHolder> {
    // 數(shù)據(jù)源
    private ArrayList<HashMap<String, Object>> listItem;
    //上下文
    private Context context;
    //數(shù)據(jù)總數(shù)量
    private int count = 0;
    //layoutHelper對象
    LayoutHelper layoutHelper;


    public MyAdapter(Context context, LayoutHelper layoutHelper,int count,
                     ArrayList<HashMap<String, Object>> listItem){
        this.context = context;
        this.layoutHelper = layoutHelper;
        this.count = count;
        this.listItem = listItem;
    }

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

    @NonNull
    @Override
    public MainViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
        return new MainViewHolder(LayoutInflater.from(context).inflate(R.layout.item,viewGroup,false));

    }

    @Override
    public void onBindViewHolder(@NonNull MainViewHolder viewHolder, int position) {
        viewHolder.Text.setText((String) listItem.get(position).get("ItemTitle"));
        viewHolder.image.setImageResource((Integer) listItem.get(position).get("ItemImage"));
    }

    @Override
    public int getItemCount() {
        return count;
    }


    class MainViewHolder extends RecyclerView.ViewHolder {

        public TextView Text;
        public ImageView image;

        public MainViewHolder(View root) {
            super(root);
            // 綁定視圖
            Text = (TextView) root.findViewById(R.id.Item);
            image = (ImageView) root.findViewById(R.id.Image);
        }

        public TextView getText() {
            return Text;
        }

    }
}
案例二(仿淘寶主頁面)
public class TaoBaoActivity extends AppCompatActivity {
    //不同item必須不同的viewtype
    int BANNER_VIEW_TYPE = 1;
    int MENU_VIEW_TYPE = 2;
    int NEWS_VIEW_TYPE = 3;
    int TITLE_VIEW_TYPE = 4;
    int GRID_VIEW_TYPE = 5;
    //廣告位
    int[] ITEM_URL = {R.mipmap.item1, R.mipmap.item2, R.mipmap.item3, R.mipmap.item4, R.mipmap.item5};
    //應(yīng)用位
    String[] ITEM_NAMES = {"天貓", "聚劃算", "天貓國際", "外賣", "天貓超市", "充值中心", "飛豬旅行", "領(lǐng)金幣", "拍賣", "分類"};
    int[] IMG_URLS = {R.mipmap.ic_tian_mao, R.mipmap.ic_ju_hua_suan, R.mipmap.ic_tian_mao_guoji, R.mipmap.ic_waimai,
            R.mipmap.ic_chaoshi, R.mipmap.ic_voucher_center, R.mipmap.ic_travel, R.mipmap.ic_tao_gold, R.mipmap.ic_auction,
            R.mipmap.ic_classify};
    //高顏值商品位
    int[] GRID_URL = {R.mipmap.flashsale1, R.mipmap.flashsale2, R.mipmap.flashsale3, R.mipmap.flashsale4};
    private RecyclerView mRecyclerView;
    //存放各個模塊的適配器
    private List<DelegateAdapter.Adapter> mAdapters;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_taobao);
        initView();
    }

    private void initView() {
        //初始化適配器集合
        mAdapters = new LinkedList<>();
        //初始化適配器
        mRecyclerView = findViewById(R.id.recycler);

        //初始化VirtualLayoutManager
        VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
        //設(shè)置mRecyclerView的setLayoutManager
        mRecyclerView.setLayoutManager(layoutManager);
        //設(shè)置回收復(fù)用池大小堡牡,(如果一屏內(nèi)相同類型的 View 個數(shù)比較多咖气,需要設(shè)置一個合適的大小嗜憔,防止來回滾動時重新創(chuàng)建 View):
        RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
        mRecyclerView.setRecycledViewPool(viewPool);
        viewPool.setMaxRecycledViews(0, 10);
        //創(chuàng)建一個VLayout中的DelegateAdapter適配器 因?yàn)檫@個適配器可以添加適配器集合
        DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, true);
        mRecyclerView.setAdapter(delegateAdapter);


        //設(shè)置banner的適配器
        BaseDelegateAdapter baseDelegateAdapter = new BaseDelegateAdapter(this,new LinearLayoutHelper(),
                R.layout.vlayout_banner,1,BANNER_VIEW_TYPE){
            //重寫onBindViewHolder
            @Override
            public void onBindViewHolder(@NonNull BaseViewHolder baseViewHolder, int i) {
                super.onBindViewHolder(baseViewHolder, i);
                ArrayList<String> arrayList = new ArrayList<>();
                arrayList.add("http://gank.io/images/f4f6d68bf30147e1bdd4ddbc6ad7c2a2");
                arrayList.add("http://gank.io/images/dc75cbde1d98448183e2f9514b4d1320");
                // 綁定數(shù)據(jù)
                Banner mBanner = baseViewHolder.getView(R.id.banner);
                //設(shè)置banner樣式
                mBanner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR);
                //設(shè)置圖片加載器
                mBanner.setImageLoader(new GlideImageLoader());
                //設(shè)置圖片集合
                mBanner.setImages(arrayList);
                //設(shè)置banner動畫效果
                mBanner.setBannerAnimation(Transformer.DepthPage);
                //設(shè)置標(biāo)題集合(當(dāng)banner樣式有顯示title時)
                //        mBanner.setBannerTitles(titles);
                //設(shè)置自動輪播沾乘,默認(rèn)為true
                mBanner.isAutoPlay(true);
                //設(shè)置輪播時間
                mBanner.setDelayTime(5000);
                //設(shè)置指示器位置(當(dāng)banner模式中有指示器時)
                mBanner.setIndicatorGravity(BannerConfig.CENTER);
                //banner設(shè)置方法全部調(diào)用完畢時最后調(diào)用
                mBanner.start();

                mBanner.setOnBannerListener(new OnBannerListener() {
                    @Override
                    public void OnBannerClick(int position) {
                        Toast.makeText(getApplicationContext(), "banner點(diǎn)擊了" + position, Toast.LENGTH_SHORT).show();
                    }
                });

            }
        };
        mAdapters.add(baseDelegateAdapter);


        //menu
        // 在構(gòu)造函數(shù)設(shè)置每行的網(wǎng)格個數(shù)
        GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(5);
        gridLayoutHelper.setPadding(0, 16, 0, 16);
        gridLayoutHelper.setVGap(16);// 控制子元素之間的垂直間距
        gridLayoutHelper.setHGap(0);// 控制子元素之間的水平間距
        gridLayoutHelper.setBgColor(Color.WHITE);
        BaseDelegateAdapter menuAdapter = new BaseDelegateAdapter(this, gridLayoutHelper, R.layout.vlayout_menu
                , 10, MENU_VIEW_TYPE) {
            @Override
            public void onBindViewHolder(BaseViewHolder holder, @SuppressLint("RecyclerView") final int position) {
                super.onBindViewHolder(holder, position);
                holder.setText(R.id.tv_menu_title_home, ITEM_NAMES[position] + "");
                holder.setImageResource(R.id.iv_menu_home, IMG_URLS[position]);
                holder.getView(R.id.ll_menu_home).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Toast.makeText(getApplicationContext(), ITEM_NAMES[position], Toast.LENGTH_SHORT).show();
                    }
                });
            }
        };
        mAdapters.add(menuAdapter);

        //news----->
        BaseDelegateAdapter newsAdapter = new BaseDelegateAdapter(this, new LinearLayoutHelper()
                , R.layout.vlayout_news, 1, NEWS_VIEW_TYPE) {
            @Override
            public void onBindViewHolder(BaseViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                MarqueeView marqueeView1 = holder.getView(R.id.marqueeView1);
                MarqueeView marqueeView2 = holder.getView(R.id.marqueeView2);

                List<String> info1 = new ArrayList<>();
                info1.add("天貓超市最近發(fā)大活動啦亿昏,快來搶");
                info1.add("沒有最便宜,只有更便宜芥颈!");

                List<String> info2 = new ArrayList<>();
                info2.add("這個是用來搞笑的惠勒,不要在意這寫小細(xì)節(jié)!");
                info2.add("啦啦啦啦浇借,我就是來搞笑的捉撮!");

                marqueeView1.startWithList(info1);
                marqueeView2.startWithList(info2);
                // 在代碼里設(shè)置自己的動畫
                marqueeView1.startWithList(info1, R.anim.anim_bottom_in, R.anim.anim_top_out);
                marqueeView2.startWithList(info2, R.anim.anim_bottom_in, R.anim.anim_top_out);

                marqueeView1.setOnItemClickListener(new MarqueeView.OnItemClickListener() {
                    @Override
                    public void onItemClick(int position, TextView textView) {
                        Toast.makeText(getApplicationContext(), textView.getText().toString(), Toast.LENGTH_SHORT).show();
                    }
                });
                marqueeView2.setOnItemClickListener(new MarqueeView.OnItemClickListener() {
                    @Override
                    public void onItemClick(int position, TextView textView) {
                        Toast.makeText(getApplicationContext(), textView.getText().toString(), Toast.LENGTH_SHORT).show();
                    }
                });
            }
        };
        mAdapters.add(newsAdapter);

        //這里我就循環(huán)item 實(shí)際項(xiàng)目中不同的ITEM 繼續(xù)往下走就行
        for (int i = 0; i < ITEM_URL.length; i++) {
            //item1 title
            final int finalI = i;
            BaseDelegateAdapter titleAdapter = new BaseDelegateAdapter(this, new LinearLayoutHelper(), R.layout.vlayout_title, 1, TITLE_VIEW_TYPE) {
                @Override
                public void onBindViewHolder(BaseViewHolder holder, int position) {
                    super.onBindViewHolder(holder, position);
                    holder.setImageResource(R.id.iv, ITEM_URL[finalI]);
                }
            };
            mAdapters.add(titleAdapter);
            //item1 gird
            GridLayoutHelper gridLayoutHelper1 = new GridLayoutHelper(2);
            gridLayoutHelper.setMargin(0, 0, 0, 0);
            gridLayoutHelper.setPadding(0, 0, 0, 0);
            gridLayoutHelper.setVGap(0);// 控制子元素之間的垂直間距
            gridLayoutHelper.setHGap(0);// 控制子元素之間的水平間距
            gridLayoutHelper.setBgColor(Color.WHITE);
            gridLayoutHelper.setAutoExpand(true);//是否自動填充空白區(qū)域
            BaseDelegateAdapter girdAdapter = new BaseDelegateAdapter(this, gridLayoutHelper1, R.layout.vlayout_grid
                    , 4, GRID_VIEW_TYPE) {
                @Override
                public void onBindViewHolder(BaseViewHolder holder, @SuppressLint("RecyclerView") final int position) {
                    super.onBindViewHolder(holder, position);
                    int item = GRID_URL[position];
                    ImageView iv = holder.getView(R.id.iv);
                    Glide.with(getApplicationContext()).load(item).into(iv);

                    iv.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Toast.makeText(getApplicationContext(), "item" + position, Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            };
            mAdapters.add(girdAdapter);
        }


        delegateAdapter.addAdapters(mAdapters);
    }
}
public class BaseDelegateAdapter extends DelegateAdapter.Adapter<BaseViewHolder> {
    //helper類
    private LayoutHelper mLayoutHelper;
    //總數(shù)量
    private int mCount = -1;
    //xmllayout的id
    private int mLayoutId = -1;
    //上下文
    private Context mContext;
    //itemView 類型
    private int mViewTypeItem = -1;

    public BaseDelegateAdapter(Context context, LayoutHelper layoutHelper, int layoutId, int count, int viewTypeItem) {
        this.mContext = context;
        this.mCount = count;
        this.mLayoutHelper = layoutHelper;
        this.mLayoutId = layoutId;
        this.mViewTypeItem = viewTypeItem;
    }
    @Override
    public LayoutHelper onCreateLayoutHelper() {
        return mLayoutHelper;
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        if (viewType == mViewTypeItem) {
            return new BaseViewHolder(LayoutInflater.from(mContext).inflate(mLayoutId, viewGroup, false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder baseViewHolder, int i) {

    }

    @Override
    public int getItemViewType(int position) {
        return  mViewTypeItem;
    }

    @Override
    public int getItemCount() {
        return mCount;
    }


}

demo下載地址https://github.com/283006603/VLayout

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怕品,一起剝皮案震驚了整個濱河市妇垢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖闯估,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灼舍,死亡現(xiàn)場離奇詭異,居然都是意外死亡涨薪,警方通過查閱死者的電腦和手機(jī)骑素,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刚夺,“玉大人献丑,你說我怎么就攤上這事∠拦茫” “怎么了创橄?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長莽红。 經(jīng)常有香客問我妥畏,道長,這世上最難降的妖魔是什么安吁? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任醉蚁,我火速辦了婚禮,結(jié)果婚禮上鬼店,老公的妹妹穿的比我還像新娘网棍。我一直安慰自己,他們只是感情好薪韩,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布确沸。 她就那樣靜靜地躺著,像睡著了一般俘陷。 火紅的嫁衣襯著肌膚如雪罗捎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天拉盾,我揣著相機(jī)與錄音桨菜,去河邊找鬼。 笑死捉偏,一個胖子當(dāng)著我的面吹牛倒得,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播夭禽,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼霞掺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了讹躯?” 一聲冷哼從身側(cè)響起菩彬,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤缠劝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后骗灶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惨恭,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年耙旦,在試婚紗的時候發(fā)現(xiàn)自己被綠了脱羡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡免都,死狀恐怖锉罐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绕娘,我是刑警寧澤氓鄙,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站业舍,受9級特大地震影響抖拦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舷暮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一态罪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧下面,春花似錦复颈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至机杜,卻和暖如春帜讲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背椒拗。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工似将, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蚀苛。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓在验,卻偏偏與公主長得像,于是被迫代替她去往敵國和親堵未。 傳聞我的和親對象是個殘疾皇子腋舌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容