1. 程式人生 > >vlayout實戰 —— 仿淘寶首頁

vlayout實戰 —— 仿淘寶首頁

引言

實戰之前,您可能先要學習vlayout的原理和使用場景,

體驗

ScreenShot

  • Demo下載體驗,下載 ,或者掃描二維碼下載

實現

VirtualLayout是一個針對RecyclerView的LayoutManager擴充套件, 主要提供一整套佈局方案和佈局間的元件複用的問題。

設計思路

通過定製化的LayoutManager,接管整個RecyclerView的佈局邏輯;LayoutManager管理了一系列LayoutHelper,LayoutHelper負責具體佈局邏輯實現的地方;每一個LayoutHelper負責頁面某一個範圍內的元件佈局;不同的LayoutHelper可以做不同的佈局邏輯,因此可以在一個RecyclerView頁面裡提供異構的佈局結構,這就能比系統自帶的LinearLayoutManager、GridLayoutManager等提供更加豐富的能力。同時支援擴充套件LayoutHelper來提供更多的佈局能力。

主要功能

  • 預設通用佈局實現,解耦所有的View和佈局之間的關係: Linear, Grid, 吸頂, 浮動, 固定位置等。
    • LinearLayoutHelper: 線性佈局
    • GridLayoutHelper: Grid佈局, 支援橫向的colspan
    • FixLayoutHelper: 固定佈局,始終在螢幕固定位置顯示
    • ScrollFixLayoutHelper: 固定佈局,但之後當頁面滑動到該圖片區域才顯示, 可以用來做返回頂部或其他書籤等
    • FloatLayoutHelper: 浮動佈局,可以固定顯示在螢幕上,但使用者可以拖拽其位置
    • ColumnLayoutHelper: 欄格佈局,都佈局在一排,可以配置不同列之間的寬度比值
    • SingleLayoutHelper: 通欄佈局,只會顯示一個元件View
    • OnePlusNLayoutHelper: 一拖N佈局,可以配置1-5個子元素
    • StickyLayoutHelper: stikcy佈局, 可以配置吸頂或者吸底
    • StaggeredGridLayoutHelper: 瀑布流佈局,可配置間隔高度/寬度
  • 上述預設實現裡可以大致分為兩類:一是非fix型別佈局,像線性、Grid、欄格等,它們的特點是佈局在整個頁面流裡,隨頁面滾動而滾動;另一類就是fix型別的佈局,它們的子節點往往不隨頁面滾動而滾動。
  • 所有除佈局外的元件複用,VirtualLayout將用來管理大的模組佈局組合,擴充套件了RecyclerView,使得同一RecyclerView內的元件可以複用,減少View的建立和銷燬過程。

使用

版本請參考mvn repository上的最新版本(目前最新版本是1.2.1),最新的 aar 都會發布到 jcenter 和 MavenCentral 上,確保配置了這兩個倉庫源,然後引入aar依賴:

compile ('com.alibaba.android:vlayout:1.2.1@aar') {
    transitive = true
}

初始化LayoutManager

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

recyclerView.setLayoutManager(layoutManager);

設定回收複用池大小,(如果一屏內相同型別的 View 個數比較多,需要設定一個合適的大小,防止來回滾動時重新建立 View):

RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
recyclerView.setRecycledViewPool(viewPool);
viewPool.setMaxRecycledViews(0, 10);

基類介面卡

package com.zxl.vlayoutdemo.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.alibaba.android.vlayout.DelegateAdapter;
import com.alibaba.android.vlayout.LayoutHelper;
import com.chad.library.adapter.base.BaseViewHolder;

/**
 * 基類介面卡
 * Created by zxl on 2017/8/28.
 */

public class BaseDelegateAdapter extends DelegateAdapter.Adapter<BaseViewHolder> {

    private LayoutHelper mLayoutHelper;
    private int mCount = -1;
    private int mLayoutId = -1;
    private Context mContext;
    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;
    }

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

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {

    }

    /**
     * 必須重寫不然會出現滑動不流暢的情況
     *
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        return mViewTypeItem;
    }

    //條目數量
    @Override
    public int getItemCount() {
        return mCount;
    }
}

介面卡使用

BaseDelegateAdapter bannerAdapter = new BaseDelegateAdapter(this, new LinearLayoutHelper()
                , R.layout.vlayout_banner, 1, BANNER_VIEW_TYPE) {
            @Override
            public void onBindViewHolder(BaseViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                ArrayList<String> arrayList = new ArrayList<>();
                arrayList.add("http://bpic.wotucdn.com/11/66/23/55bOOOPIC3c_1024.jpg!/fw/780/quality/90/unsharp/true/compress/true/watermark/url/L2xvZ28ud2F0ZXIudjIucG5n/repeat/true");
                arrayList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1505470629546&di=194a9a92bfcb7754c5e4d19ff1515355&imgtype=0&src=http%3A%2F%2Fpics.jiancai.com%2Fimgextra%2Fimg01%2F656928666%2Fi1%2FT2_IffXdxaXXXXXXXX_%2521%2521656928666.jpg");
                // 繫結資料
                Banner mBanner = holder.getView(R.id.banner);
                //設定banner樣式
                mBanner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR);
                //設定圖片載入器
                mBanner.setImageLoader(new GlideImageLoader());
                //設定圖片集合
                mBanner.setImages(arrayList);
                //設定banner動畫效果
                mBanner.setBannerAnimation(Transformer.DepthPage);
                //設定標題集合(當banner樣式有顯示title時)
                //        mBanner.setBannerTitles(titles);
                //設定自動輪播,預設為true
                mBanner.isAutoPlay(true);
                //設定輪播時間
                mBanner.setDelayTime(5000);
                //設定指示器位置(當banner模式中有指示器時)
                mBanner.setIndicatorGravity(BannerConfig.CENTER);
                //banner設定方法全部呼叫完畢時最後呼叫
                mBanner.start();

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

最後

Demo地址 下載
不明白的地方請留言。