一、前言:
最近在把一个界面封装成一个viewGroup的过程中发现了一个问题,viewgroup(ViewGroup是九宫格,九宫格上面添加蒙层)里面的 内容始终没有显示出来,在百度了好久,发现了问题出在那里。
因为没有重写onMeasure的方法里的 measureChildren(widthMeasureSpec, heightMeasureSpec);,重新之后ViewGroup的内容才会正常显示。
十二宫格视图:

二、重要
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
//控件的宽度
int screenWidth = MeasureSpec.getSize(widthMeasureSpec);
// int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
//控件的高度
int screenHeight = MeasureSpec.getSize(heightMeasureSpec);
//测量子控件大小,必须调用,否则不显示页面内容
// 计算出所有的childView的宽和高,调用后,它所有的childView的宽和高的值就被确定,也即getMeasuredWidth()有值了。
measureChildren(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int width = getMeasuredWidth();
final int height = getMeasuredHeight();
final int childLeft = getPaddingLeft();
final int childTop = getPaddingTop();
//由于这里child只有一个所以将整个长宽都设置给child
View child = this.getChildAt(0);
child.layout(childLeft, childTop, width - getPaddingRight(), height - getPaddingBottom());
}
三、十二宫格代码:
1、动态添加子布局
MyVideoGroup myVideoGroup = page1.findViewById(R.id.my_group);
//添加子布局
for (TXCloudVideoView rlTxVideo :page0List){
myVideoGroup.addView(rlTxVideo);
}
2、自定义VideoGroup
/**
* 自定义VideoGroup
*/
public class MyVideoGroup extends ViewGroup {
private static int screenHeightGap;//竖向间距高度
private static int screenWidthGap;//横向间距高度
private static int screenWidth;
private static int screenHeight;
private final Context context;
//ViewGroup的中间布局Width范围
int layoutWidth;
//ViewGroup的中间布局Height范围
int layoutHeight;
/**
* 获取单个视频的宽高
*
* @param displayMode 0是九宫格,其它是12宫格
* @param page1List
*/
static int zoom_old_w;//小方块的高度
static int zoom_old_h;//小方块的高度
private boolean adjustMode;
private TXCloudVideoView bigVideoView;
private ClassLiveBean classLiveBean;
int dp7;
public MyVideoGroup(Context context) {
super(context);
this.context = context;
initView();
}
public MyVideoGroup(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initView();
}
public MyVideoGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
initView();
}
private void initView() {
dp7 = (int) BaseApplication.getContext().getResources().getDimension(R.dimen.dp_7);
// screenHeightGap = (int) getResources().getDimension(R.dimen.dp_3);//竖向间距高度
// screenWidthGap = (int) getResources().getDimension(R.dimen.dp_3);//横向间距高度
screenHeightGap = 0;//竖向间距高度
screenWidthGap = 0;//横向间距高度
}
int bigHeightGrap;
public int getBigHeightGrap() {
return bigHeightGrap;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
//控件的宽度
screenWidth = MeasureSpec.getSize(widthMeasureSpec);
// int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
//控件的高度
screenHeight = MeasureSpec.getSize(heightMeasureSpec);
// 计算出所有的childView的宽和高,调用后,它所有的childView的宽和高的值就被确定,也即getMeasuredWidth()有值了。
measureChildren(widthMeasureSpec, heightMeasureSpec);
//测量
getWidthHeigth(getChildCount());
int zoom_w = screenWidth / screenHeight > 0.75 ? screenHeight : screenWidth;
int zoom_h = zoom_w * 4 / 3;
// int bigWidthGrap = (screenWidth - zoom_w) / 2;
int bigHeightGrap = (screenHeight - zoom_h) / 2;
this.bigHeightGrap = bigHeightGrap;
}
/**
* 页面布局
*
* @param changed
* @param l 左
* @param t 上
* @param r 右
* @param b 下
*/
int left;
int top;
int right;
int bottom;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
try {
if (adjustMode) {
//放大
int zoom_w = screenWidth / screenHeight > 0.75 ? screenHeight : screenWidth;
int zoom_h = zoom_w * 4 / 3;
int bigWidthGrap = (screenWidth - zoom_w) / 2;
int bigHeightGrap = (screenHeight - zoom_h) / 2;
if (bigVideoView != null) {
LayoutParams params = new LayoutParams(zoom_w, zoom_h);
bigVideoView.setLayoutParams(params);
//测量
measureChildren(zoom_w, zoom_h + bigHeightGrap);
//重新布局
bigVideoView.layout(bigWidthGrap, bigHeightGrap, zoom_w, zoom_h + bigHeightGrap);
// Log.d("LYY", "====放大的绘制=====");
}
} else {
// Log.d("LYY", "====九宫格的绘制=====");
//九宫格布局
if (getChildCount() > 0) {
setChildLayout(getChildCount());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param childCount
*/
private void setChildLayout(int childCount) {
try {
//横向空隙
int widthGrap = (screenWidth - layoutWidth) / 2;
//高度空隙
int heightGrap = (screenHeight - layoutHeight) / 2; //横向空隙
if (childCount == 2) {
for (int i = 0; i < getChildCount(); i++) {
TXCloudVideoView txCloudVideoView = (TXCloudVideoView) getChildAt(i);
LayoutParams otherVideo = new LayoutParams(zoom_old_w, zoom_old_h);
txCloudVideoView.setLayoutParams(otherVideo);
int position = i % 2;
//左,上,右,下
left = widthGrap + position * zoom_old_w + position * screenWidthGap;
top = heightGrap;
right = left + zoom_old_w;
bottom = top + zoom_old_h;
//测量
txCloudVideoView.measure(MeasureSpec.makeMeasureSpec((int) zoom_old_w, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) zoom_old_h, MeasureSpec.EXACTLY));
//布局
txCloudVideoView.layout(left, top, right, bottom);
}
} else {
// Log.d("LUO","布局个数==========="+getChildCount());
for (int i = 0; i < getChildCount(); i++) {
TXCloudVideoView txCloudVideoView = (TXCloudVideoView) getChildAt(i);
LayoutParams otherVideo = new LayoutParams(zoom_old_w, zoom_old_h);
txCloudVideoView.setLayoutParams(otherVideo);
Log.d("LUO", "screenWidth:" + screenWidth + "====screenHeight:" + screenHeight + "===layoutWidth:" + layoutWidth + "====layoutHeight: " + layoutHeight);
Log.d("LUO", "widthGrap:" + widthGrap + "====zoom_old_w:" + zoom_old_w + "===heightGrap:" + heightGrap);
if (i < 3) {
int position = i % 3;
//左,上,右,下
left = widthGrap + position * zoom_old_w + position * screenWidthGap;
top = heightGrap;
right = left + zoom_old_w;
bottom = top + zoom_old_h;
} else if (i < 6) {
int position = (i - 3) % 3;
//左,上,右,下
left = widthGrap + position * zoom_old_w + position * screenWidthGap;
top = heightGrap + zoom_old_h + screenHeightGap;
right = left + zoom_old_w;
bottom = top + zoom_old_h;
} else if (i < 9) {
int position = (i - 6) % 3;
//左,上,右,下
left = widthGrap + position * zoom_old_w + position * screenWidthGap;
top = heightGrap + zoom_old_h * 2 + screenHeightGap * 2;
right = left + zoom_old_w;
bottom = top + zoom_old_h;
} else if (i < 12) {
int position = (i - 9) % 3;
//左,上,右,下
left = widthGrap + position * zoom_old_w + position * screenWidthGap;
top = heightGrap + zoom_old_h * 3 + screenHeightGap * 3;
right = left + zoom_old_w;
bottom = top + zoom_old_h;
}
// Log.d("LUO", "====left:" + left+"===top:"+top+"=====right:"+right+"=====bottom:"+bottom);
//测量
txCloudVideoView.measure(MeasureSpec.makeMeasureSpec((int) zoom_old_w, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) zoom_old_h, MeasureSpec.EXACTLY));
//布局
txCloudVideoView.layout(left, top, right, bottom);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//记录上次的宽高
private int lastChildCount = 0;
public void getWidthHeigth(int childCount) {
try {
if (lastChildCount != childCount) {
lastChildCount = childCount;
if (childCount == 9) {
//九宫格
int small9Width = 0;
if (classLiveBean != null) {
small9Width = classLiveBean.getSmall9Width();
}
if (small9Width == 0) {
//宽高比例
zoom_old_w = screenWidth / screenHeight > 0.75 ? (screenHeight - screenHeightGap * 3) / 3 : (screenWidth - screenWidthGap * 3) / 3;
int h = zoom_old_w * 4 / 3 + screenHeightGap * 2;
if (h > screenHeight) {
zoom_old_h = (screenHeight - screenHeightGap * 3) / 4;
zoom_old_w = zoom_old_h * 3 / 4;
} else {
zoom_old_h = zoom_old_w * 4 / 3;
}
//真正布局范围
layoutWidth = zoom_old_w * 3 + screenWidthGap * 2;
layoutHeight = zoom_old_h * 3 + screenHeightGap * 2;
if (classLiveBean != null) {
classLiveBean.setSmall9Width(layoutWidth);
classLiveBean.setSmall9Height(layoutHeight);
}
} else {
layoutWidth = small9Width;
layoutHeight = classLiveBean.getSmall9Height();
}
} else if (childCount == 12) {
//十二宫格
int small12Width = 0;
if (classLiveBean != null) {
small12Width = classLiveBean.getSmall12Width();
}
if (small12Width == 0) {
zoom_old_w = screenWidth / screenHeight > 0.75 ? (screenHeight - screenHeightGap * 3) / 4 : (screenWidth - screenWidthGap * 3) / 3;
int h = (zoom_old_w * 4 / 3) * 4 + screenHeightGap * 3;
if (h > screenHeight) {
zoom_old_h = (screenHeight - screenHeightGap * 3) / 4;
zoom_old_w = zoom_old_h * 3 / 4;
} else {
zoom_old_h = zoom_old_w * 4 / 3;
}
//真正布局范围
layoutHeight = zoom_old_h * 4 + screenHeightGap * 3;
//异常屏幕
boolean phone = PhoneUtils.isPhone();
if (!phone && layoutHeight >= 2400) {
zoom_old_h = zoom_old_h - dp7;
zoom_old_w = zoom_old_h * 3 / 4;
layoutHeight = zoom_old_h * 4 + screenHeightGap * 3;
}
layoutWidth = zoom_old_w * 3 + screenWidthGap * 2;
if (classLiveBean != null) {
classLiveBean.setSmall12Width(layoutWidth);
classLiveBean.setSmall12Height(layoutHeight);
}
} else {
layoutWidth = small12Width;
layoutHeight = classLiveBean.getSmall12Height();
}
} else if (childCount == 2) {
//二宫格
zoom_old_w = screenWidth / screenHeight > 0.75 ? (screenHeight - screenHeightGap * 2) / 2 : (screenWidth - screenWidthGap * 2) / 2;
int h = zoom_old_w * 4 / 3;
if (h > screenHeight) {
zoom_old_h = (screenHeight - screenHeightGap * 3) / 4;
zoom_old_w = zoom_old_h * 3 / 4;
} else {
zoom_old_h = zoom_old_w * 4 / 3;
}
//真正布局范围
layoutWidth = zoom_old_w * 2 + screenWidthGap;
layoutHeight = zoom_old_h + screenHeightGap;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置视图裁剪的圆角半径
*
* @param radius
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setClipViewCornerRadius(View view, final int radius) {
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// //不支持5.0版本以下的系统
// return;
// }
// if (view == null) return;
// if (radius <= 0) {
// return;
// }
//
// view.setOutlineProvider(new ViewOutlineProvider() {
// @Override
// public void getOutline(View view, Outline outline) {
// outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius);
// }
// });
// view.setClipToOutline(true);
}
public void setLayout(boolean adjustMode, TXCloudVideoView bigVideoView) {
this.adjustMode = adjustMode;
this.bigVideoView = bigVideoView;
Log.d("LUO", "====放大=====" + adjustMode);
//控件会重新执行 onMesure() onLayout()
requestLayout();
}
/**
* 设置公共变量
*
* @param classLiveBean
*/
public void setModel(ClassLiveBean classLiveBean) {
this.classLiveBean = classLiveBean;
}
}
网友评论