正文
今天我们来自定义一个ViewGroup,让它可以根据图片的数量显示不同的布局
我们在微信逛朋友圈的时候会看到有图片的朋友圈,当只有一张图片的时候,显示是铺满所在区域的,当有9张的时候,是九宫格的形式显示的,那么我们能不能根据图片的数量显示不同的布局呢,比如两张的时候我想让其均分,三张的时候我想一张大图在左,另外两张小图在右,还有其他数量也可以自己想象
你有没有想到用什么方法实现这个需求呢,你可能会想到用不同的布局文件,只要你不嫌麻烦,因为你的布局数量和图片数量是成正比的,所以布局是比较浪费资源的,那有什么好方法吗,当然有,就是我们今天要讲的自定义ViewGroup
正式开始
我们知道ViewGroup是控件的组合,它可以添加View到其内部,我们可以新建一个类并继承ViewGroup
public class VideoLayout extends ViewGroup {
public VideoLayout(Context context) {
this(context, null);
}
public VideoLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
}
}
我们重写一个ViewGroup来满足今天的需求其实需要重写onMeasure和onLayout方法,还有一个onDraw方法不用管
我们创建好之后就可以开始编写代码了,下面是完整代码
PostContentLayout.java
package com.yk.mchat.app.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class PostContentLayout extends ViewGroup {
public static final int PIC_ONE = 1;
public static final int PIC_TWO = 2;
public static final int PIC_THREE = 3;
public static final int PIC_FOUR = 4;
public static final int PIC_FIVE = 5;
public static final int PIC_SIX = 6;
public static final int PIC_SEVEN = 7;
public static final int PIC_EIGHT = 8;
public static final int PIC_NINE = 9;
public PostContentLayout(Context context) {
super(context);
}
public PostContentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int childCount = getChildCount();
if (childCount == 0) {
return;
}
switch (childCount) {
case PIC_ONE:
onMeasureOne(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_TWO:
onMeasureTwo(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_THREE:
onMeasureThree(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_FOUR:
onMeasureFour(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_FIVE:
onMeasureFive(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_SIX:
onMeasureSix(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_SEVEN:
onMeasureSeven(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_EIGHT:
onMeasureEight(widthMeasureSpec, heightMeasureSpec);
break;
case PIC_NINE:
onMeasureNice(widthMeasureSpec, heightMeasureSpec);
break;
default:
break;
}
}
private void onMeasureOne(int widthMeasureSpec, int heightMeasureSpec) {
View child = getChildAt(0);
child.measure(widthMeasureSpec, heightMeasureSpec);
}
private void onMeasureTwo(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 2, MeasureSpec.EXACTLY);
child.measure(childWidth, heightMeasureSpec);
}
}
private void onMeasureThree(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
View mainChild = getChildAt(0);
int mainChildWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 2, MeasureSpec.EXACTLY);
mainChild.measure(mainChildWidth, heightMeasureSpec);
for (int i = 1; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 2, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 2, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
}
private void onMeasureFour(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 2, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 2, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
}
private void onMeasureFive(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 2, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 2, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
for (int i = 2; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 3, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 2, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
}
private void onMeasureSix(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
View mainChild = getChildAt(0);
int mainChildWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 3 * 2, MeasureSpec.EXACTLY);
int mainChildHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 3 * 2, MeasureSpec.EXACTLY);
mainChild.measure(mainChildWidth, mainChildHeight);
for (int i = 1; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 3, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 3, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
}
private void onMeasureSeven(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
View mainChild = getChildAt(0);
int mainChildWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 2, MeasureSpec.EXACTLY);
int mainChildHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 2, MeasureSpec.EXACTLY);
mainChild.measure(mainChildWidth, mainChildHeight);
for (int i = 1; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 2, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 4, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
}
private void onMeasureEight(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
View mainChild = getChildAt(0);
int mainChildWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 4 * 3, MeasureSpec.EXACTLY);
int mainChildHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 4 * 3, MeasureSpec.EXACTLY);
mainChild.measure(mainChildWidth, mainChildHeight);
for (int i = 1; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 4, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 4, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
}
private void onMeasureNice(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec) / 3, MeasureSpec.EXACTLY);
int childHeight = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) / 3, MeasureSpec.EXACTLY);
child.measure(childWidth, childHeight);
}
}
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
int childCount = getChildCount();
if (childCount == 0) {
return;
}
switch (childCount) {
case PIC_ONE:
onLayoutOne();
break;
case PIC_TWO:
onLayoutTwo();
break;
case PIC_THREE:
onLayoutThree();
break;
case PIC_FOUR:
onLayoutFour();
break;
case PIC_FIVE:
onLayoutFive();
break;
case PIC_SIX:
onLayoutSix();
break;
case PIC_SEVEN:
onLayoutSeven();
break;
case PIC_EIGHT:
onLayoutEight();
break;
case PIC_NINE:
onLayoutNine();
break;
default:
break;
}
}
private void onLayoutOne() {
View child = getChildAt(0);
child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
}
private void onLayoutTwo() {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * i, 0, child.getMeasuredWidth() * (i + 1), child.getMeasuredHeight());
}
}
private void onLayoutThree() {
int childCount = getChildCount();
View mainChild = getChildAt(0);
mainChild.layout(0, 0, mainChild.getMeasuredWidth(), mainChild.getMeasuredHeight());
for (int i = 1; i < childCount; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth(), child.getMeasuredHeight() * (i - 1), child.getMeasuredWidth() * 2, child.getMeasuredHeight() * i);
}
}
private void onLayoutFour() {
int childCount = getChildCount();
for (int i = 0; i < 2; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * i, 0, child.getMeasuredWidth() * (i + 1), child.getMeasuredHeight());
}
for (int i = 2; i < childCount; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 2), child.getMeasuredHeight(), child.getMeasuredWidth() * (i - 1), child.getMeasuredHeight() * 2);
}
}
private void onLayoutFive() {
int childCount = getChildCount();
for (int i = 0; i < 2; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * i, 0, child.getMeasuredWidth() * (i + 1), child.getMeasuredHeight());
}
for (int i = 2; i < childCount; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 2), child.getMeasuredHeight(), child.getMeasuredWidth() * (i - 1), child.getMeasuredHeight() * 2);
}
}
private void onLayoutSix() {
int childCount = getChildCount();
View mainChild = getChildAt(0);
mainChild.layout(0, 0, mainChild.getMeasuredWidth(), mainChild.getMeasuredHeight());
for (int i = 1; i < 3; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * 2, child.getMeasuredHeight() * (i - 1), child.getMeasuredWidth() * 3, child.getMeasuredHeight() * i);
}
for (int i = 3; i < childCount; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 3), child.getMeasuredHeight() * 2, child.getMeasuredWidth() * (i - 2), child.getMeasuredHeight() * 3);
}
}
private void onLayoutSeven() {
int childCount = getChildCount();
View mainChild = getChildAt(0);
mainChild.layout(0, 0, mainChild.getMeasuredWidth(), mainChild.getMeasuredHeight());
for (int i = 1; i < 3; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth(), child.getMeasuredHeight() * (i - 1), child.getMeasuredWidth() * 2, child.getMeasuredHeight() * i);
}
for (int i = 3; i < 5; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 3), child.getMeasuredHeight() * 2, child.getMeasuredWidth() * (i - 2), child.getMeasuredHeight() * 3);
}
for (int i = 5; i < childCount; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 5), child.getMeasuredHeight() * 3, child.getMeasuredWidth() * (i - 4), child.getMeasuredHeight() * 4);
}
}
private void onLayoutEight() {
int childCount = getChildCount();
View mainChild = getChildAt(0);
mainChild.layout(0, 0, mainChild.getMeasuredWidth(), mainChild.getMeasuredHeight());
for (int i = 1; i < 4; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * 3, child.getMeasuredHeight() * (i - 1), child.getMeasuredWidth() * 4, child.getMeasuredHeight() * i);
}
for (int i = 4; i < childCount; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 4), child.getMeasuredHeight() * 3, child.getMeasuredWidth() * (i - 3), child.getMeasuredHeight() * 4);
}
}
private void onLayoutNine() {
int childCount = getChildCount();
for (int i = 0; i < 3; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * i, 0, child.getMeasuredWidth() * (i + 1), child.getMeasuredHeight());
}
for (int i = 3; i < 6; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 3), child.getMeasuredHeight(), child.getMeasuredWidth() * (i - 2), child.getMeasuredHeight() * 2);
}
for (int i = 6; i < 9; i++) {
View child = getChildAt(i);
child.layout(child.getMeasuredWidth() * (i - 6), child.getMeasuredHeight() * 2, child.getMeasuredWidth() * (i - 5), child.getMeasuredHeight() * 3);
}
}
}
里面的方法都写得比较清楚,你可以复制下来,然后试着往这个ViewGroup中addView
今天就到这里。