recyclerView 实现复杂的item布局(如淘宝、京东、商城类首页)

前言

现在各种电商如火如荼,首页页面设计也颇有色彩。
之前项目也是一个电商类购物app,主页设计了好几套样式。
其中一个样式如下图相似涉及到: 轮播广告图banner、viewPager的轮播、沉浸式、
item的复杂分割线、以及自定义的主页头条ViewFlipper使用、glide图片加载、其他的琐碎知识点也略有涉及到。

看下Gif效果图:

1

再下引用的第三方控件:

     //banner
    implementation 'com.youth.banner:banner:1.4.10'
    //RecyclerView
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    //RecyclerView Adapter
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.40'
    //图片加载
    implementation 'com.github.bumptech.glide:glide:3.7.0'
    //沉浸式
    implementation 'com.jaeger.statusbarutil:library:1.5.1'
    //retrofit2 转化器 gson
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
HomeFragment基本代码

这里说明一下:item的复杂分割线

根据GridLayoutManager的getSpanSize方法可以动态的设置item跨列数; new GridLayoutManager(getContext(), 6);
这里的6(自己设置的最好设置成偶数)就相当于分母,6默认显示一整行(1列),下面的 3 和 2 就相当于分子
返回3就是(1/2)所以此类型对应的是2列,返回2就是(1/3)所以此类型对应的是3列!

例如:
根据getItemViewType返回的itemtype,第一个position显示为轮播图,
所以返回的是gridManager.getSpanCount(); 即:return 6
如果是2张图占满一行,那么1张图就是占整行的二分之一,既6/2=3, return 3即可。

public class HomeFragment extends BaseFragment {
    private LinearLayout mToolbar;
    private RecyclerView mRecyclerView;
    private List<TestBean> data;
    private int height;

    @Override
    public int getLayoutId() {
        return R.layout.app_fragment_home;
    }

    @Override
    public void initView(View mView) {
        mToolbar = mView.findViewById(R.id.toolbar);
        mRecyclerView = mView.findViewById(R.id.app_home_list);
    }

     /**
     * 懒加载方法    
     */
    @Override
    public void lazyLoad() {
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 6);
        mRecyclerView.setLayoutManager(gridLayoutManager);
        String jsonData = new String(getAssertsFile(getContext(), "content.json"));
        data = new Gson().fromJson(jsonData, new TypeToken<List<TestBean>>() {
        }.getType());
        TestHomeAdapter adapter = new TestHomeAdapter();
        adapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() {
            @Override
            public int getSpanSize(GridLayoutManager gridLayoutManager, int position) {
                int type = data.get(position).getType();
                if (type == 1 || type == 3 || type == 2 || type == 5 || type == 6) {
                    return 6;
                } else if (type == 4) {
                    return 2;
                } else if (type == 7) {
                    return 3;
                }
                return 0;
            }
        });
        mRecyclerView.setAdapter(adapter);
        adapter.setHeaderView(getHeaderView(mRecyclerView));
        adapter.setNewData(data);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            private int totalDy = 0;

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                totalDy += dy;
                if (totalDy <= height) {
                    float alpha = (float) totalDy / height;
                    mToolbar.setBackgroundColor(ColorUtils.blendARGB(Color.TRANSPARENT
                            , ContextCompat.getColor(getContext(), R.color.white), alpha));
                } else {
                    mToolbar.setBackgroundColor(ColorUtils.blendARGB(Color.TRANSPARENT
                            , ContextCompat.getColor(getContext(), R.color.white), 1));
                }
            }
        });
    }

    /**
     * 轮播图banner的数据设置
     */
    private View getHeaderView(RecyclerView v) {
        List<String> bannerImg = new ArrayList<>();
        bannerImg.add("https://timgsa.baidu.com/timg?
        image&quality=80&size=b9999_10000&sec=1530962561545&di=
2F0118a6576505160000018c1bc1c1d9.jpg%401280w_1l_2o_100sh.jpg");
        bannerImg.add("https://timgsa.baidu.com/timg?
d7d90171e1fd6cc69352b73e2f8df529&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%
2Fcommunity%2F017338576505290000012e7e45db9f.jpg%401280w_1l_2o_100sh.jpg");
        bannerImg.add("https://timgsa.baidu.com/timg?
5e4a5342ae724f219b004ccad7b6fa82&imgtype=jpg&er=1&src=
http%3A%2F%2Fimg.zcool.cn%2Fcommunity%
2F017e0458212939a84a0e282bca0f71.jpg%401280w_1l_2o_100sh.jpg");
        bannerImg.add("http://58.87.71.247:8080/TestFile/banner.png");
        View convertView = LayoutInflater
                .from(getContext())
                .inflate(R.layout.app_include_home_header, (ViewGroup) v.getParent(), false);
        Banner mBanner = convertView.findViewById(R.id.app_home_header_banner);
        mBanner.setImages(bannerImg)
                .setImageLoader(new GlideImageLoader())
                .setDelayTime(3000)
                .start();


        MarqueeView marqueeView = convertView.findViewById(R.id.app_home_header_problem);

        //头条数据
        List<String> problems = new ArrayList<>();
        problems.add("如何获取更多个人积分");
        problems.add("下单时服务费率规则");
        problems.add("大额预定商品详细交易流程");
        marqueeView.startWithList(problems);

        ViewGroup.LayoutParams bannerParams = mBanner.getLayoutParams();
        int resourceId = getContext().getResources().getIdentifier("status_bar_height", 
        "dimen","android");
        int statusBarHeight = getContext().getResources().getDimensionPixelSize(resourceId);
        height = bannerParams.height - statusBarHeight - 104;
        return convertView;
    }

    //模拟后台请求数据 存放在AssertsFile文件夹里
    public static byte[] getAssertsFile(Context context, String fileName) {
        InputStream inputStream = null;
        AssetManager assetManager = context.getAssets();
        try {
            inputStream = assetManager.open(fileName);
            if (inputStream == null) {
                return null;
            }

            BufferedInputStream bis = null;
            int length;
            try {
                bis = new BufferedInputStream(inputStream);
                length = bis.available();
                byte[] data = new byte[length];
                bis.read(data);

                return data;
            } catch (IOException e) {

            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (Exception e) {

                    }
                }
            }

            return null;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}
基类Fragment
public abstract class BaseFragment extends Fragment {

    View mView;
    boolean isLoad = false;
    boolean isInit = false;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (mView == null)
            mView = inflater.inflate(getLayoutId(), container, false);
        isInit = true;
        initView(mView);
        isCanLoadData();
        return mView;
    }

    public abstract void initView(View mView);

    /**
     * 视图是否已经对用户可见,系统的方法
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isCanLoadData();
    }

    /**
     * 懒加载
     */
    private void isCanLoadData() {
        if (!isInit) {
            return;
        }
        if (getUserVisibleHint() && !isLoad) {
            lazyLoad();
            isLoad = true;
        } else {
            if (isLoad) {
                stopLoad();
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isInit = false;
    }


    /**
     * 第一次加载的处理   此处可以留给加载网络去处理
     */
    public void lazyLoad() {

    }

    /**
     * 页面停止加载的处理
     */
    public void stopLoad() {

    }

    public abstract int getLayoutId();

}
核心adapter
public class TestHomeAdapter extends MultipleItemRvAdapter<TestBean, BaseViewHolder> {
    //通栏商品大图片
    public static final int TYPE_IMG = 100;
    //通栏图文
    public static final int TYPE_TEXT_AND_IMG = 200;
    //通栏文本
    public static final int TYPE_TEXT = 300;
    //三列
    public static final int TYPE_THREE_COLUMN = 400;
    //通栏水平拖动
    public static final int TYPE_HORIZONTAL_SCROLL = 500;
    //通栏窄图片
    public static final int TYPE_NARROW_IMG = 600;
    //两列
    public static final int TYPE_TWO_COLUMN = 700;
    public TestHomeAdapter() {
        super(null);
        finishInitialize();
    }

    @Override
    protected int getViewType(TestBean testBean) {
        int type = testBean.getType();
        if (type == 1) {
            return TYPE_IMG;
        } else if (type == 2) {
            return TYPE_TEXT_AND_IMG;
        } else if (type == 3) {
            return TYPE_TEXT;
        } else if (type == 4) {
            return TYPE_THREE_COLUMN;
        } else if (type == 5) {
            return TYPE_HORIZONTAL_SCROLL;
        } else if (type == 6) {
            return TYPE_NARROW_IMG;
        } else if (type == 7) {
            return TYPE_TWO_COLUMN;
        }
        return 0;
    }

    @Override
    public void registerItemProvider() {
        //通栏商品大图片
        mProviderDelegate.registerProvider(new ImgItemProvider());
        //通栏图文
        mProviderDelegate.registerProvider(new ImgAndTextItemProvider());
        //通栏文本
        mProviderDelegate.registerProvider(new TextItemProvider());
        //三列图文
        mProviderDelegate.registerProvider(new ThreeColumnItemProvider());
        //通栏横向滑动
        mProviderDelegate.registerProvider(new ScrollItemProvider());
        //通栏窄图片
        mProviderDelegate.registerProvider(new NarrowImgItemProvider());
        //两列图文
        mProviderDelegate.registerProvider(new TwoColumnItemProvider());
    }
}
demo地址:

请移步recyclerView 实现复杂的item布局(如淘宝、京东、商城类首页)


与君共勉

我要一步一步往上爬
在最高点乘着叶片往前飞
任风吹干流过的泪和汗
我要一步一步往上爬
等待阳光静静看着它的脸
小小的天有大大的梦想
我有属于我的天
任风吹干流过的泪和汗
总有一天我有属于我的天
这里写图片描述

猜你喜欢

转载自blog.csdn.net/Life_s/article/details/81298823
今日推荐