首页的最后一个布局,如图:

这个布局,可以分三个部分。
第一部分,就是那个title,左边一个图片,右边一个text,下面带个分割线。
第二部分,2个大图片。
第三部分,4个小图片。
由于是均分布局,很容易想到,又是用的RecyclerView+GridLayoutManager。
在主RecyclerView中,这3部分还是作为一个RecyclerView整体,方便设置圆弧背景。
设置单独的bean文件:
public class SalesBoxBean extends ExampleBaseBean {
private SalesBox salesbox;
public SalesBox getSalesboxBean() {
return salesbox;
}
public void setSalesboxBean(SalesBox salesbox) {
this.salesbox = salesbox;
}
}
添加数据:
SalesBoxBean salesBoxBean = new SalesBoxBean();
salesBoxBean.setSalesboxBean(model.getSalesbox());
salesBoxBean.setViewType(SALES_TYPE);
datas.add(salesBoxBean);
然后是添加Holder:
public class SalesHolder extends RecyclerView.ViewHolder {
RecyclerView salesRecycler;
public SalesHolder(@NonNull View itemView) {
super(itemView);
salesRecycler = itemView.findViewById(R.id.sales_recycler);
}
}
else if (viewType == SALES_TYPE) {
return new SalesHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.sales_box, parent, false));
}
根据typeview实现SalesHolder:
else if (holder instanceof SalesHolder) {
SalesBoxBean salesBoxBean = (SalesBoxBean) datas.get(position);
RecyclerView recyclerView = ((SalesHolder) holder).salesRecycler;
recyclerView.setLayoutManager(new GridLayoutManager(context, 2, RecyclerView.VERTICAL, false));
recyclerView.setAdapter(new SalesAdapter(salesBoxBean.getSalesboxBean()));
}
这个SalesHolder布局就是一个RecyclerView。
根据前面的分析,用RecyclerView+GridLayoutManager实现这部分布局。
spancount设置为2(和后面的onAttachedToRecyclerView配合使用,设置占据空间大小。),salesBoxBean.getSalesboxBean()数据传递给SalesAdapter。
这个布局稍微有点复杂,先看看这个数据SalesBox的组成。
public class SalesBox {
private String icon;
private String moreUrl;
private CommonModel bigCard1;
private CommonModel bigCard2;
private CommonModel smallCard1;
private CommonModel smallCard2;
private CommonModel smallCard3;
private CommonModel smallCard4;
.....
}
icon是title左边的图片,moreUrl是点击右边文字进入的链接。
下面是2个大图和4个小图。
根据前面的分析,这个RecyclerView分为3大布局,7个item(title作为一个占满widht的整体,加上6个1/2widht屏幕的图片)。
title:sales_title.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="44dp"
>
<com.li.gohome.util.MyImageView
android:id="@+id/sales_title_left"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:scaleType="fitXY"
android:layout_height="15dp"/>
<TextView
android:id="@+id/sales_title_right"
android:layout_marginRight="3dp"
android:text="获得更多福利>"
android:textSize="12dp"
android:paddingLeft="10dp"
android:paddingRight="8dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
android:textColor="@android:color/white"
android:background="@drawable/sales_text_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1dp"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#f2f2f2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
这个title布局,有几个要注意的地方:
首先是image,发现设置了hight,这个图片的高度并没有变化,于是找到了一个属性
android:scaleType="fitXY",对应flutter代码里面也设置了fit: BoxFit.fill,这个属性能让图片撑满布局。
然后就是textview,
他有一个渐变的背景,这里设置了一个渐变的xml:
android:background="@drawable/sales_text_bg"
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<!-- 指定圆角矩形的4个圆角的半径 -->
<corners android:topLeftRadius="12dp"
android:topRightRadius="12dp"
android:bottomLeftRadius="12dp"
android:bottomRightRadius="12dp"
/>
<!-- 指定使用渐变背景色,使用sweep类型的渐变,颜色从红色到绿色再到蓝色 -->
<gradient android:startColor="#ffff4e63"
android:endColor="#ffff6cc9"
android:angle="45"
android:centerX="0.5"
android:centerY="0.5"
/>
</shape>
corners设置圆角,gradient设置渐变色。
[android:angle]渐变色的角度,举例来说,0代表从上至下颜色渐变;45代表从左至右颜色渐变;90代表从下至上颜色渐变…
文字和背景有一定的距离,这里就要用
android:paddingLeft="10dp"
android:paddingRight="8dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
来设置一下文字和背景的距离。
android:layout_marginRight="3dp"是整个textview距离外面的布局。
Padding 为内边框,指该控件内部内容,如文本/图片距离该控件的边距
Margin 为外边框,指该控件距离边父控件的边距。
接下来,是两种图片。
sales_big_image.xml:
<?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">
<com.li.gohome.util.MyImageView
android:id="@+id/sales_big_image"
android:layout_width="match_parent"
android:layout_height="129dp"/>
</LinearLayout>
sales_small_image.xml
和上面一样,只是高度为80dp。
注意,sales_title.xml和下面的2个图片,widht都要为match_parent,要不然不能撑满空间。
回到SalesAdapter。
Holder布局:
public class TitleHolder extends RecyclerView.ViewHolder {
MyImageView imageView;
TextView textView;
public TitleHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.sales_title_left);
textView = itemView.findViewById(R.id.sales_title_right);
}
}
public class ImageBigHolder extends RecyclerView.ViewHolder {
MyImageView imageView;
public ImageBigHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.sales_big_image);
}
}
public class ImageSmallHolder extends RecyclerView.ViewHolder {
MyImageView imageView;
public ImageSmallHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.sales_small_image);
}
}
关键点在getItemViewType。
public int getItemViewType(int position) {
if (position == 0) {
return TITLE_TYPE;
} else if (position == 1 || position == 2) {
return IMAGE_BIG_TYPE;
}else if(position > 2){
return IMAGE_SMALL_TYPE;
}
return super.getItemViewType(position);
}
position为0的时候,为TITLE_TYPE,1和2的时候是IMAGE_BIG_TYPE,剩下4个是IMAGE_SMALL_TYPE。
用onAttachedToRecyclerView来确定他们7个item占的布局空间:
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (TITLE_TYPE == getItemViewType(position)) {
return 2;
} else if (IMAGE_BIG_TYPE == getItemViewType(position)
|| IMAGE_SMALL_TYPE == getItemViewType(position)) {
return 1;
} else {
return 2;
}
}
});
}
}
onAttachedToRecyclerView方法和前面设置的spancount一起配合,2为占满屏,1为一半屏。
onCreateViewHolder绑定Holder:
if (viewType == TITLE_TYPE) {
return new TitleHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.sales_title, parent, false));
} else if (viewType == IMAGE_BIG_TYPE) {
return new ImageBigHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.sales_big_image, parent, false));
}else if (viewType == IMAGE_SMALL_TYPE) {
return new ImageSmallHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.sales_small_image, parent, false));
}
将数据加入到集合方便调用:
private List<String> datas = new ArrayList<>();
datas.add(salesbox.getIcon());
datas.add(salesbox.getMoreUrl());
datas.add(salesbox.getBigCard1().getIcon());
datas.add(salesbox.getBigCard2().getIcon());
datas.add(salesbox.getSmallCard1().getIcon());
datas.add(salesbox.getSmallCard2().getIcon());
datas.add(salesbox.getSmallCard3().getIcon());
datas.add(salesbox.getSmallCard4().getIcon());
salesbox.getIcon和salesbox.getMoreUrl作为title整体,所以
public int getItemCount() {
return datas.size() - 1;
}
接下来,onBindViewHolder绑定数据:
if (holder instanceof TitleHolder) {
((TitleHolder) holder).imageView.setImageURL(salesbox.getIcon());
} else if (holder instanceof ImageBigHolder) {
((ImageBigHolder) holder).imageView.setImageURL(datas.get(position+1));
} else if (holder instanceof ImageSmallHolder) {
((ImageSmallHolder) holder).imageView.setImageURL(datas.get(position+1));
}
这样,整个布局就完成了,详见代码:
https://github.com/doudousang/recyclerview_items2.git
参考代码:
Android中设置Imageview的图片充满整个布局
android 圆角边框、渐变背景的TextView
Android RecyclerView加载复杂布局
Android在ImageView上直接显示网络图片
网友评论