商城项目实战 | 5.1 RecyclerView 和 CardView 更配 实现首页商品分类

本文为菜鸟窝作者刘婷的连载。”商城项目实战”系列来聊聊仿”京东淘宝的购物商城”如何实现。

在前面的两篇文章《商城项目实战 | 4.1 RecyclerView 使用完全解析 体验艺术般的控件(一)》和《商城项目实战 | 4.2 RecyclerView 使用完全解析 体验艺术般的控件(二)》中已经对 RecyclerView 的属性以及使用做了非常详细的介绍了,这里就不多说了,我们就先来讲讲 CardView 吧。

CardView 的概述

1. CardView是什么

CardView 和 RecyclerView 一样,也是在安卓5.0提出的,顾名思义,CardView 是一款卡片式控件,可以设置阴影、圆角等属性,卡片效果很优美,同时在用户体验上更加受到好评。

2. CardView 的基本属性

了解控件的基本属性,可以知道如何更好的使用该控件,其基本属性如下。

<attr name="cardBackgroundColor" format="color" /><!-- 背景色 -->
<attr name="cardCornerRadius" format="dimension" /><!-- 边缘弧度数 -->
<attr name="cardElevation" format="dimension" /> <!-- 高度 -->
<attr name="cardMaxElevation" format="dimension" /> <!-- 最大高度 -->
<!-- 设置内边距 设置内边距,v21+的版本和之前的版本仍旧具有一样的计算方式-->
<attr name="cardUseCompatPadding" format="boolean" />  
<!-- 在v20和之前的版本中添加内边距,这个属性是为了防止卡片内容和边角的重叠 -->
<attr name="cardPreventCornerOverlap" format="boolean" />

<!-- 下面是卡片边界距离内部的距离-->
<attr name="contentPadding" format="dimension" />
<attr name="contentPaddingLeft" format="dimension" />
<attr name="contentPaddingRight" format="dimension" />
<attr name="contentPaddingTop" format="dimension" />
<attr name="contentPaddingBottom" format="dimension" />

实现首页商品分类

对于 CardView 和 RecyclerView 都有了一定的认识了,那些下面就要开始实现商品分类的效果了,具体的效果如下图所示。

《商城项目实战 | 5.1 RecyclerView 和 CardView 更配 实现首页商品分类》

上面的广告轮播在文章《商城项目实战 | 3.1 AndroidImageSlider 实现炫酷轮播广告》已经介绍了,下面的商品分类就是这次需要实现的。

1. Gradle 添加依赖

在 module 下的 build.gradle 文件下面添加对 RecyclerView 和 CardView 的依赖。

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:support-v4:25.2.0'
    compile 'com.android.support:recyclerview-v7:25.2.0'
    compile 'com.android.support:cardview-v7:25.2.0'
}

2. 定义实体类

根据商品分类的效果展示,可以了解到实体类的属性有 title 、大图以及两张小图,所以定义实体类如下。

public class HomeCategoryInfo extends CategoryInfo {
    private String name;//分类名称
    private int imgBig;//大图
    private int imgSmallTop;//上面的小图
    private int imgSmallBottom;//下面的小图

    public HomeCategoryInfo(String name, int imgBig, int imgSmallTop, int imgSmallBottom) {
        this.name = name;
        this.imgBig = imgBig;
        this.imgSmallTop = imgSmallTop;
        this.imgSmallBottom = imgSmallBottom;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImgBig() {
        return imgBig;
    }

    public void setImgBig(int imgBig) {
        this.imgBig = imgBig;
    }

    public int getImgSmallTop() {
        return imgSmallTop;
    }

    public void setImgSmallTop(int imgSmallTop) {
        this.imgSmallTop = imgSmallTop;
    }

    public int getImgSmallBottom() {
        return imgSmallBottom;
    }

    public void setImgSmallBottom(int imgSmallBottom) {
        this.imgSmallBottom = imgSmallBottom;
    }
}

3. 布局设计

布局中有标题、大图和两张小图,而且第一项中是大图在右边,两张小图在左边,而第二项中是大图在左边,两张小图在右边,所以至少要设计两个布局文件,但是首先是要在首页 Fragment 中写入 RecyclerView 。

<android.support.v7.widget.RecyclerView
        android:id="@+id/home_recycler_category"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView>

下面就是 item 项的布局设计了,需要有个布局文件,唯一的差别是图片的摆放左右有所不同,这里就展示大图在左边的 layout 文件了,大图在右边的可以直接仿照的写就行了。因为布局中的控件是一样的,所以 id 也就使用相同的就可以了。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_gravity="center"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="#fff"
    app:contentPadding="10dp"
    app:cardCornerRadius="4dp">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/category_tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="热门活动"
            android:textSize="20dp"
            android:textColor="@color/black"
            android:paddingTop="10dp"
            />
        <View
            style="@style/line_vertical"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="10dp"></View>
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/category_img_big"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />

            <View
                android:id="@+id/line"
                style="@style/line_horizontal"
                />
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >
                <ImageView
                    android:id="@+id/category_img_top"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    />

                <View
                    android:id="@+id/line2"
                    style="@style/line_vertical"

                    ></View>
                <ImageView
                    android:id="@+id/category_img_bottom"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"

                    />
            </LinearLayout>
        </LinearLayout>

    </LinearLayout>
</android.support.v7.widget.CardView>

4. 定义 Adapter

列表 item 的布局文件已经写好了,接下来需要准备的就是适配器 Adapter 了。在定义的时候注意第一项中是大图在右边,两张小图在左边,而第二项中是大图在左边,两张小图在右边,所以需要判断下根据 position 的位置来确定布局的样式。定义的 Adapter 必须继承于 RecyclerView.Adapter,然后绑定布局和数据,具体代码如下。

    private  static int VIEW_TYPE_L=0;
    private  static int VIEW_TYPE_R=1;
    private LayoutInflater mInflater;
    private List<HomeCategoryInfo> mDatas;

    public HomeCategoryAdapter(List<HomeCategoryInfo> datas){
        mDatas = datas;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
        mInflater = LayoutInflater.from(viewGroup.getContext());
        if(type == VIEW_TYPE_R){

            return  new ViewHolder(mInflater.inflate(R.layout.recycler_item_even_layout,viewGroup,false));
       }

        return  new ViewHolder(mInflater.inflate(R.layout.recycler_item_odd_layout,viewGroup,false));
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        HomeCategoryInfo category = mDatas.get(i);
        viewHolder.textTitle.setText(category.getName());
        viewHolder.imageViewBig.setImageResource(category.getImgBig());
        viewHolder.imageViewSmallTop.setImageResource(category.getImgSmallTop());
        viewHolder.imageViewSmallBottom.setImageResource(category.getImgSmallBottom());
    }

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


    @Override
    public int getItemViewType(int position) {

        if(position % 2==0){
            return  VIEW_TYPE_R;
        }
        else return VIEW_TYPE_L;

    }

    static  class ViewHolder extends RecyclerView.ViewHolder{
        TextView textTitle;
        ImageView imageViewBig;
        ImageView imageViewSmallTop;
        ImageView imageViewSmallBottom;

        public ViewHolder(View itemView) {
            super(itemView);

            textTitle = (TextView) itemView.findViewById(R.id.category_tv_title);
            imageViewBig = (ImageView) itemView.findViewById(R.id.category_img_big);
            imageViewSmallTop = (ImageView) itemView.findViewById(R.id.category_img_top);
            imageViewSmallBottom = (ImageView) itemView.findViewById(R.id.category_img_bottom);
        }

    }

5. 实现商品分类

在首页的 Fragment 中声明 RecyclerView ,设置适配器,绑定数据,设置 RecyclerView 的 ItemDecoration 间隔线和 LayoutManager 为线性布局,完成设置就可以了。

public void initRecyclerView() {
        recyclerCategory = (RecyclerView) view.findViewById(R.id.home_recycler_category);
        List<HomeCategoryInfo> datas = new ArrayList<>(15);

        HomeCategoryInfo category = new HomeCategoryInfo("热门活动", R.drawable.img_big_1, R.drawable.img_1_small1, R.drawable.img_1_small2);
        datas.add(category);

        category = new HomeCategoryInfo("有利可图", R.drawable.img_big_4, R.drawable.img_4_small1, R.drawable.img_4_small2);
        datas.add(category);
        category = new HomeCategoryInfo("品牌街", R.drawable.img_big_2, R.drawable.img_2_small1, R.drawable.img_2_small2);
        datas.add(category);

        category = new HomeCategoryInfo("金融街 包赚翻", R.drawable.img_big_1, R.drawable.img_3_small1, R.drawable.imag_3_small2);
        datas.add(category);

        category = new HomeCategoryInfo("超值购", R.drawable.img_big_0, R.drawable.img_0_small1, R.drawable.img_0_small2);
        datas.add(category);

        mAdatper = new HomeCategoryAdapter(datas);

        recyclerCategory.setAdapter(mAdatper);

        recyclerCategory.addItemDecoration(new DividerItemDecoration());

        recyclerCategory.setLayoutManager(new LinearLayoutManager(this.getActivity()));
    }

6. 效果图展示

运行代码,获取到最终效果,如下图所示。

《商城项目实战 | 5.1 RecyclerView 和 CardView 更配 实现首页商品分类》 效果图

本文为菜鸟窝作者刘婷的连载。”商城项目实战”系列来聊聊仿”京东淘宝的购物商城”如何实现。

在前面的两篇文章《商城项目实战 | 4.1 RecyclerView 使用完全解析 体验艺术般的控件(一)》和《商城项目实战 | 4.2 RecyclerView 使用完全解析 体验艺术般的控件(二)》中已经对 RecyclerView 的属性以及使用做了非常详细的介绍了,这里就不多说了,我们就先来讲讲 CardView 吧。

CardView 的概述

1. CardView是什么

CardView 和 RecyclerView 一样,也是在安卓5.0提出的,顾名思义,CardView 是一款卡片式控件,可以设置阴影、圆角等属性,卡片效果很优美,同时在用户体验上更加受到好评。

2. CardView 的基本属性

了解控件的基本属性,可以知道如何更好的使用该控件,其基本属性如下。

<attr name="cardBackgroundColor" format="color" /><!-- 背景色 -->
<attr name="cardCornerRadius" format="dimension" /><!-- 边缘弧度数 -->
<attr name="cardElevation" format="dimension" /> <!-- 高度 -->
<attr name="cardMaxElevation" format="dimension" /> <!-- 最大高度 -->
<!-- 设置内边距 设置内边距,v21+的版本和之前的版本仍旧具有一样的计算方式-->
<attr name="cardUseCompatPadding" format="boolean" />  
<!-- 在v20和之前的版本中添加内边距,这个属性是为了防止卡片内容和边角的重叠 -->
<attr name="cardPreventCornerOverlap" format="boolean" />

<!-- 下面是卡片边界距离内部的距离-->
<attr name="contentPadding" format="dimension" />
<attr name="contentPaddingLeft" format="dimension" />
<attr name="contentPaddingRight" format="dimension" />
<attr name="contentPaddingTop" format="dimension" />
<attr name="contentPaddingBottom" format="dimension" />

实现首页商品分类

对于 CardView 和 RecyclerView 都有了一定的认识了,那些下面就要开始实现商品分类的效果了,具体的效果如下图所示。

《商城项目实战 | 5.1 RecyclerView 和 CardView 更配 实现首页商品分类》

上面的广告轮播在文章《商城项目实战 | 3.1 AndroidImageSlider 实现炫酷轮播广告》已经介绍了,下面的商品分类就是这次需要实现的。

1. Gradle 添加依赖

在 module 下的 build.gradle 文件下面添加对 RecyclerView 和 CardView 的依赖。

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:support-v4:25.2.0'
    compile 'com.android.support:recyclerview-v7:25.2.0'
    compile 'com.android.support:cardview-v7:25.2.0'
}

2. 定义实体类

根据商品分类的效果展示,可以了解到实体类的属性有 title 、大图以及两张小图,所以定义实体类如下。

public class HomeCategoryInfo extends CategoryInfo {
    private String name;//分类名称
    private int imgBig;//大图
    private int imgSmallTop;//上面的小图
    private int imgSmallBottom;//下面的小图

    public HomeCategoryInfo(String name, int imgBig, int imgSmallTop, int imgSmallBottom) {
        this.name = name;
        this.imgBig = imgBig;
        this.imgSmallTop = imgSmallTop;
        this.imgSmallBottom = imgSmallBottom;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImgBig() {
        return imgBig;
    }

    public void setImgBig(int imgBig) {
        this.imgBig = imgBig;
    }

    public int getImgSmallTop() {
        return imgSmallTop;
    }

    public void setImgSmallTop(int imgSmallTop) {
        this.imgSmallTop = imgSmallTop;
    }

    public int getImgSmallBottom() {
        return imgSmallBottom;
    }

    public void setImgSmallBottom(int imgSmallBottom) {
        this.imgSmallBottom = imgSmallBottom;
    }
}

3. 布局设计

布局中有标题、大图和两张小图,而且第一项中是大图在右边,两张小图在左边,而第二项中是大图在左边,两张小图在右边,所以至少要设计两个布局文件,但是首先是要在首页 Fragment 中写入 RecyclerView 。

<android.support.v7.widget.RecyclerView
        android:id="@+id/home_recycler_category"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView>

下面就是 item 项的布局设计了,需要有个布局文件,唯一的差别是图片的摆放左右有所不同,这里就展示大图在左边的 layout 文件了,大图在右边的可以直接仿照的写就行了。因为布局中的控件是一样的,所以 id 也就使用相同的就可以了。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_gravity="center"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="#fff"
    app:contentPadding="10dp"
    app:cardCornerRadius="4dp">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/category_tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="热门活动"
            android:textSize="20dp"
            android:textColor="@color/black"
            android:paddingTop="10dp"
            />
        <View
            style="@style/line_vertical"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="10dp"></View>
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/category_img_big"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />

            <View
                android:id="@+id/line"
                style="@style/line_horizontal"
                />
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >
                <ImageView
                    android:id="@+id/category_img_top"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    />

                <View
                    android:id="@+id/line2"
                    style="@style/line_vertical"

                    ></View>
                <ImageView
                    android:id="@+id/category_img_bottom"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"

                    />
            </LinearLayout>
        </LinearLayout>

    </LinearLayout>
</android.support.v7.widget.CardView>

4. 定义 Adapter

列表 item 的布局文件已经写好了,接下来需要准备的就是适配器 Adapter 了。在定义的时候注意第一项中是大图在右边,两张小图在左边,而第二项中是大图在左边,两张小图在右边,所以需要判断下根据 position 的位置来确定布局的样式。定义的 Adapter 必须继承于 RecyclerView.Adapter,然后绑定布局和数据,具体代码如下。

    private  static int VIEW_TYPE_L=0;
    private  static int VIEW_TYPE_R=1;
    private LayoutInflater mInflater;
    private List<HomeCategoryInfo> mDatas;

    public HomeCategoryAdapter(List<HomeCategoryInfo> datas){
        mDatas = datas;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
        mInflater = LayoutInflater.from(viewGroup.getContext());
        if(type == VIEW_TYPE_R){

            return  new ViewHolder(mInflater.inflate(R.layout.recycler_item_even_layout,viewGroup,false));
       }

        return  new ViewHolder(mInflater.inflate(R.layout.recycler_item_odd_layout,viewGroup,false));
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        HomeCategoryInfo category = mDatas.get(i);
        viewHolder.textTitle.setText(category.getName());
        viewHolder.imageViewBig.setImageResource(category.getImgBig());
        viewHolder.imageViewSmallTop.setImageResource(category.getImgSmallTop());
        viewHolder.imageViewSmallBottom.setImageResource(category.getImgSmallBottom());
    }

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


    @Override
    public int getItemViewType(int position) {

        if(position % 2==0){
            return  VIEW_TYPE_R;
        }
        else return VIEW_TYPE_L;

    }

    static  class ViewHolder extends RecyclerView.ViewHolder{
        TextView textTitle;
        ImageView imageViewBig;
        ImageView imageViewSmallTop;
        ImageView imageViewSmallBottom;

        public ViewHolder(View itemView) {
            super(itemView);

            textTitle = (TextView) itemView.findViewById(R.id.category_tv_title);
            imageViewBig = (ImageView) itemView.findViewById(R.id.category_img_big);
            imageViewSmallTop = (ImageView) itemView.findViewById(R.id.category_img_top);
            imageViewSmallBottom = (ImageView) itemView.findViewById(R.id.category_img_bottom);
        }

    }

5. 实现商品分类

在首页的 Fragment 中声明 RecyclerView ,设置适配器,绑定数据,设置 RecyclerView 的 ItemDecoration 间隔线和 LayoutManager 为线性布局,完成设置就可以了。

public void initRecyclerView() {
        recyclerCategory = (RecyclerView) view.findViewById(R.id.home_recycler_category);
        List<HomeCategoryInfo> datas = new ArrayList<>(15);

        HomeCategoryInfo category = new HomeCategoryInfo("热门活动", R.drawable.img_big_1, R.drawable.img_1_small1, R.drawable.img_1_small2);
        datas.add(category);

        category = new HomeCategoryInfo("有利可图", R.drawable.img_big_4, R.drawable.img_4_small1, R.drawable.img_4_small2);
        datas.add(category);
        category = new HomeCategoryInfo("品牌街", R.drawable.img_big_2, R.drawable.img_2_small1, R.drawable.img_2_small2);
        datas.add(category);

        category = new HomeCategoryInfo("金融街 包赚翻", R.drawable.img_big_1, R.drawable.img_3_small1, R.drawable.imag_3_small2);
        datas.add(category);

        category = new HomeCategoryInfo("超值购", R.drawable.img_big_0, R.drawable.img_0_small1, R.drawable.img_0_small2);
        datas.add(category);

        mAdatper = new HomeCategoryAdapter(datas);

        recyclerCategory.setAdapter(mAdatper);

        recyclerCategory.addItemDecoration(new DividerItemDecoration());

        recyclerCategory.setLayoutManager(new LinearLayoutManager(this.getActivity()));
    }

6. 效果图展示

运行代码,获取到最终效果,如下图所示。

《商城项目实战 | 5.1 RecyclerView 和 CardView 更配 实现首页商品分类》 效果图

关注公众号免费领取『N套客户端实战项目教程』和『140套Android优秀开源项目源码』

《商城项目实战 | 5.1 RecyclerView 和 CardView 更配 实现首页商品分类》 扫我”

    原文作者:菜鸟窝
    原文地址: https://www.jianshu.com/p/0d029b3b119f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞