在前面的两篇文章《商城项目实战 | 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 都有了一定的认识了,那些下面就要开始实现商品分类的效果了,具体的效果如下图所示。
上面的广告轮播在文章《商城项目实战 | 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. 效果图展示
运行代码,获取到最终效果,如下图所示。
作者:刘婷