利用RecyclerView做一个商城页面的效果

之前一直在想商城首页怎么做,里面有Banner、recyclerView、GridView等等,之前想着是在最外层用ScrollView包裹起来,里面用一个整体布局来写,实际效果是ScrollView会和recyclerView等可滑动组件冲突,造成明显卡顿。我决定潜心研究下怎么实现,现在,它来了,利用RecyclerView的getitemViewType来做,因为之前没太关注这个,实在太丢人了。现在让我们一起来看看怎么做吧!

1、主界面就是一个RecyclerView
 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".test.TestActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

2、主界面逻辑(使用假数据,看大体效果就好)

public class TestActivity extends BaseActivity {//此处的BaseActivity只是我封装的一个基类

    private RecyclerView recycler_view_test;

    private final List<ModuleBean> moduleBeanList = new ArrayList<>();
    private final List<TodayBean> todayBeanList = new ArrayList<>();
    private final List<PinpaiBean> pinpaiBeanList = new ArrayList<>();
    private final List<DapeiqsBean> dapeiqsBeanList = new ArrayList<>();

    @Override//绑定布局
    protected int bindLayout() {
        return R.layout.activity_test;
    }

    @SuppressLint("WrongConstant")
    @Override//初始化RecyclerView 
    protected void initView() {
        recycler_view_test = findViewById(R.id.recycler_view_test);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(OrientationHelper.VERTICAL);
        recycler_view_test.setLayoutManager(linearLayoutManager);
    }

    @Override//初始化数据
    protected void initData() {

        moduleBeanList.add(new ModuleBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        moduleBeanList.add(new ModuleBean("https://img0.baidu.com/it/u=2072688771,1371754200&fm=26&fmt=auto&gp=0.jpg"));
        moduleBeanList.add(new ModuleBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));

        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题1"));
        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题2"));
        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题3"));
        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题4"));
        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题5"));
        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题6"));
        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题7"));
        todayBeanList.add(new TodayBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg", "标题8"));

        pinpaiBeanList.add(new PinpaiBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
                                              //http://image.baidu.com/search/detail?ct=503316480&z=undefined&tn=baiduimagedetail&ipn=d&word=%E5%9B%BE%E7%89%87%20%E9%AB%98%E6%B8%85&step_word=&ie=utf-8&in=&cl=2&lm=-1&st=undefined&hd=undefined&latest=undefined&copyright=undefined&cs=3791295982,3858283543&os=4194041564,3716508751&simid=0,0&pn=28&rn=1&di=221210&ln=1354&fr=&fmq=1626936619868_R&fm=&ic=undefined&s=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&is=0,0&istype=0&ist=&jit=&bdtype=0&spn=0&pi=0&gsm=0&objurl=https%3A%2F%2Fgimg2.baidu.com%2Fimage_search%2Fsrc%3Dhttp%253A%252F%252F01.minipic.eastday.com%252F20170823%252F20170823110935_d41d8cd98f00b204e9800998ecf8427e_6.jpeg%26refer%3Dhttp%253A%252F%252F01.minipic.eastday.com%26app%3D2002%26size%3Df9999%2C10000%26q%3Da80%26n%3D0%26g%3D0n%26fmt%3Djpeg%3Fsec%3D1629528343%26t%3D95792c279bf6fde34737b1d2b1eb787b&rpstart=0&rpnum=0&adpicid=0&nojc=undefined
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
        dapeiqsBeanList.add(new DapeiqsBean("https://img0.baidu.com/it/u=1922023258,536583512&fm=26&fmt=auto&gp=0.jpg"));
    }

    @Override//事件监听
    protected void bindEvent() {
        //初始化适配器,添加数据
        HomeRecycleViewAdapter homeRecycleViewAdapter = new HomeRecycleViewAdapter(this,
                moduleBeanList, todayBeanList, pinpaiBeanList, dapeiqsBeanList);
        //设置适配器
        recycler_view_test.setAdapter(homeRecycleViewAdapter);
    }
}

3、HomeRecyclerViewAdapter适配器代码

public class HomeRecycleViewAdapter extends RecyclerView.Adapter {

    /**
     * 4种类型
     */
    /**
     * 类型1:--使用banner实现
     */
    public static final int BLACK_5_BANNER0 = 0;
    /**
     * 类型2:--使用GridView实现
     */
    public static final int TODAY_NEW_GV1 = 1;
    /**
     * 类型3:--使用ImageView实现
     */
    public static final int PIN_PAI_IV2 = 2;

    /**
     * 类型4:--使用RecyclerView实现
     */
    public static final int DAPEIQS_GV3 = 3;

    /**
     * 当前类型
     */
    public int currentType = BLACK_5_BANNER0;

    private final Context mContext;
    private final List<ModuleBean> moduleBeanList;
    private final List<TodayBean> dataBeanList;
    private final List<PinpaiBean> pinpaiBeanList;
    private final List<DapeiqsBean> dapeiqsBeanList;
    //以后用它来初始化布局
    private final LayoutInflater mLayoutInflater;

    //构造方法,用来接收上下文、数据
    public HomeRecycleViewAdapter(Context context, List<ModuleBean> moduleBeanList,
                                  List<TodayBean> dataBeanList, List<PinpaiBean> pinpaiBeanList,
                                  List<DapeiqsBean> dapeiqsBeanList) {
        this.mContext = context;
        this.moduleBeanList = moduleBeanList;
        this.dataBeanList = dataBeanList;
        this.pinpaiBeanList = pinpaiBeanList;
        this.dapeiqsBeanList = dapeiqsBeanList;
        //以后用它来初始化布局
        mLayoutInflater = LayoutInflater.from(mContext);

        Log.d("moduleBeanList.size", moduleBeanList.size() + "");
        Log.d("moduleBeanList.size", dataBeanList.size() + "");
        Log.d("moduleBeanList.size", pinpaiBeanList.size() + "");
        Log.d("moduleBeanList.size", dapeiqsBeanList.size() + "");
    }


    //相当于getView创建ViewHolder布局
    @NonNull
    @Override//不同的类型加载不同的布局
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == BLACK_5_BANNER0) {//使用banner实现
            return new BBNViewHolder(mContext, mLayoutInflater.inflate(R.layout.banner_viewpager, parent, false));
        }else if (viewType == TODAY_NEW_GV1){//使用GridView实现
            return new TODAYViewHolder(mContext, mLayoutInflater.inflate(R.layout.tpdayv, parent, false));
        }else if (viewType == PIN_PAI_IV2){//使用ImageView实现
            return new PINPAIViewHolder(mContext, mLayoutInflater.inflate(R.layout.iv_pinpai, parent, false));
        }else if (viewType == DAPEIQS_GV3){//使用RecyclerView实现
            return new DaPeiViewHolder(mContext, mLayoutInflater.inflate(R.layout.dapeiqs_rv, parent, false));
        }
        return null;
    }

    //相当于getView中的绑定数据模块
    @Override//在不同的ViewHolder里面展示数据
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (getItemViewType(position) == BLACK_5_BANNER0) {
            BBNViewHolder bbnViewHolder = (BBNViewHolder) holder;
            bbnViewHolder.setData(moduleBeanList);//将数据集合传入ViewHolder当中
        }
        else if (getItemViewType(position) == TODAY_NEW_GV1) {
            TODAYViewHolder todayViewHolder = (TODAYViewHolder) holder;
            todayViewHolder.setData(dataBeanList);//将数据集合传入ViewHolder当中
        }
        else if (getItemViewType(position) == PIN_PAI_IV2) {
            PINPAIViewHolder pinpaiViewHolder = (PINPAIViewHolder) holder;
            pinpaiViewHolder.setData(pinpaiBeanList);//将数据集合传入ViewHolder当中
        }else if (getItemViewType(position) == DAPEIQS_GV3) {
            DaPeiViewHolder dapeiViewHolder = (DaPeiViewHolder) holder;
            dapeiViewHolder.setData(dapeiqsBeanList);//将数据集合传入ViewHolder当中
        }
    }

    //总共有多少个item
    @Override
    public int getItemCount() {
        return 4;
    }

    //得到类型
    @Override
    public int getItemViewType(int position) {
        switch (position) {
            case BLACK_5_BANNER0:
                currentType = BLACK_5_BANNER0;
                break;
            case TODAY_NEW_GV1:
                currentType = TODAY_NEW_GV1;
                break;
            case PIN_PAI_IV2:
                currentType = PIN_PAI_IV2;
                break;
            case DAPEIQS_GV3:
                currentType = DAPEIQS_GV3;
                break;
        }
        return currentType;
    }

    public static class BBNViewHolder extends RecyclerView.ViewHolder {
        private final Context mContext;
        private final Banner banner;

        public BBNViewHolder(Context context, @NonNull View itemView) {
            super(itemView);
            this.mContext = context;
            banner = itemView.findViewById(R.id.banner);
        }

        public void setData(List<ModuleBean> module0data) {
            //得到图片地址的集合
            List<String> imageUrls = new ArrayList<>();
            for (int i = 0; i < module0data.size(); i++) {
                String image = module0data.get(i).getBannerUrl();
                imageUrls.add(image);
            }

            //给Banner设置数据
            banner.setAdapter(new BannerImageAdapter<String>(imageUrls) {
                @Override
                public void onBindView(BannerImageHolder holder, String data, int position, int size) {
                    //图片加载自己实现
                    Glide.with(holder.imageView)
                            .load(data)
                            .apply(RequestOptions.bitmapTransform(new RoundedCorners(30)))
                            .into(holder.imageView);
                }
            });
        }
    }

    public static class TODAYViewHolder extends RecyclerView.ViewHolder{
        private final Context mContext;
        private final GridView tpdayv_grid;

        public TODAYViewHolder(Context mContext, @NonNull View itemView) {
            super(itemView);
            this.mContext = mContext;
            tpdayv_grid = itemView.findViewById(R.id.tpdayv_grid);
        }

        public void setData(List<TodayBean> dataBeanList) {
            //此处再利用一个适配器展现数据,将数据传给新的适配器显示
            TodayGVAdapter todayGVAdapter = new TodayGVAdapter(mContext, dataBeanList);
            tpdayv_grid.setAdapter(todayGVAdapter);
        }
    }

    public static class PINPAIViewHolder extends RecyclerView.ViewHolder{

        private final Context mContext;
        private final ImageView ivNewChok;

        public PINPAIViewHolder(Context context, @NonNull View itemView) {
            super(itemView);
            this.mContext = context;
            ivNewChok  = itemView.findViewById(R.id.iv_new_chok);
        }

        public void setData(List<PinpaiBean> pinpai2data) {
            Log.d("setData", pinpai2data.get(0).getImg());
            //使用Glide加载图片
            Glide.with(mContext)
                    .load(pinpai2data.get(0).getImg())
                    .into(ivNewChok);
        }
    }

    public static class DaPeiViewHolder extends RecyclerView.ViewHolder{
        private final Context mContext;
        private final RecyclerView dapeiqs_rv;

        public DaPeiViewHolder(Context context, @NonNull View itemView) {
            super(itemView);
            this.mContext = context;
            dapeiqs_rv  = itemView.findViewById(R.id.dapeiqs_rv);
        }

        @SuppressLint("WrongConstant")
        public void setData(List<DapeiqsBean> dapeiqs6data) {
            //1.已有数据
            //2.设置适配器
            //recycleView不仅要设置适配器还要设置布局管理者,否则图片不显示
            GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, 2);
            gridLayoutManager.setOrientation(OrientationHelper.VERTICAL);
            dapeiqs_rv.setLayoutManager(gridLayoutManager);
            //将数据传给新的适配器显示
            DaPeiQSRecycleViewAdapter adapter = new DaPeiQSRecycleViewAdapter(mContext, dapeiqs6data);
            dapeiqs_rv.setAdapter(adapter);
        }
    }
}

4、4个模块的布局代码

/*banner_viewpager*/
<?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="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <com.youth.banner.Banner
        android:id="@+id/banner"
        android:layout_width="match_parent"
        android:layout_height="150dp"/>
</LinearLayout>

/*tpdayv*/
<?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">

    <GridView
        android:numColumns="4"
        android:id="@+id/tpdayv_grid"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

/*iv_pinpai*/
<?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="150dp">

    <ImageView
        android:id="@+id/iv_new_chok"
        android:layout_width="match_parent"
        android:layout_height="150dp"/>
</LinearLayout>

/*dapeiqs_rv*/
<?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="wrap_content">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/dapeiqs_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

5、 内部GridView适配器和布局的代码

/*适配器代码*/
public class TodayGVAdapter extends BaseAdapter {

    private final Context mContext;
    private final List<TodayBean> module1data;

    //构造方法接收数据和上下文
    public TodayGVAdapter(Context mContext, List<TodayBean> module1data) {
        this.mContext = mContext;
        this.module1data = module1data;
    }

    //设置数量
    @Override
    public int getCount() {
        return module1data == null ? 0 : module1data.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {
        ViewHolder holder;
        if (convertView == null) {
            //item的布局:垂直线性,ImagView+TextView
            convertView = View.inflate(mContext, R.layout.item_channel, null);
            holder = new ViewHolder();
            holder.iv_channel = (ImageView) convertView.findViewById(R.id.iv_channel);
            holder.tv_channel = (TextView) convertView.findViewById(R.id.tv_channel);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        //装配数据
        TodayBean datasig = module1data.get(position);

        //使用Glide加载图片
        Glide.with(mContext).load(datasig.getImg()).into(holder.iv_channel);
        //设置文本
        holder.tv_channel.setText(datasig.getTitle());

        return convertView;
    }

    public static class ViewHolder {
        public ImageView iv_channel;
        public TextView tv_channel;
    }
}

/*布局代码*/
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/iv_channel"
        android:src="@mipmap/ad"
        android:layout_width="30dp"
        android:layout_height="30dp"/>

    <TextView
        android:id="@+id/tv_channel"
        android:text="今日新品"
        android:textColor="@color/black"
        android:textSize="14sp"
        android:layout_marginTop="5dp"
        android:textStyle="bold"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

6、内部RecyclerView适配器和布局代码

/*适配器代码*/
public class DaPeiQSRecycleViewAdapter extends RecyclerView.Adapter {
    private final Context mContext;
    private final List<DapeiqsBean> dapeiqsBeanList;

    public DaPeiQSRecycleViewAdapter(Context mContext, List<DapeiqsBean> dapeiqsBeanList) {
        this.mContext = mContext;
        this.dapeiqsBeanList = dapeiqsBeanList;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_dapeiqs, null));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        MyViewHolder myViewHolder = (MyViewHolder) holder;
        myViewHolder.setData(position);
    }

    @Override
    public int getItemCount() {
        return dapeiqsBeanList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder{
        private final ImageView iv_figure;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);

            iv_figure = itemView.findViewById(R.id.iv_figure);
        }


        public void setData(int position) {
            DapeiqsBean dapeiqsBean = dapeiqsBeanList.get(position);
            //使用Glide加载图片
            Glide.with(mContext)
                    .load(dapeiqsBean.getImg())
                    .into(iv_figure);
        }
    }
}

/*布局代码*/
<?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">

    <ImageView
        android:id="@+id/iv_figure"
        android:layout_width="match_parent"
        android:layout_height="100dp"/>
</LinearLayout>

到此,整个代码逻辑就完成了,简单实现了一下效果。我在Banner部分采取了一个第三方组件,我将它的github地址放在这了,https://github.com/youth5201314/banner,可以去学习使用哦!
最后展示一下效果图:

好啦!不喜勿喷哈! 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值