这两天学习的时候,心情还是经常静不下来,不能让我的大脑去冷静的去思考。
做这个viewGroup也是浪费了挺多的时间,很多时候,都是自己急于求成,不冷静思考造成的。目前的这个版本还有挺多的不足:
待改进部分:
1、当前是只能通过在xml文件中添加自己提前定义好的控件来进行显示,不能像其他github开源库中通过String数组形式以java形式的进行添加。
2、对android 自定义viewgroup的显示过程还是不太熟悉:
在onlayout确定viewGroup的宽高时,
height += childView.getMeasuredHeight();//每换一次行,执行一次
本该执行两次(因为只有三行),但实际上,根据log输出和手机上的边界显示,onlayout方法执行了两次,上面的代码执行了三次。
所以 onlayuout方法在什么情况下会重新执行(当然,在一些情况下再次执行 对于自定义View也是大有好处的)
3、View的测量方面,肯定还是要拿出一点时间去探究一下(getMeasureWidth(),getWidth(),getTextBounds(),MeasureSpec.getSize(),paint.measureText(),fontMetrics参数含义,)
自己在重复一遍:
目前来看测量比较准确的方法:
宽:
int textWidth = (int) paint.measureText(mString);
高:
int height = (int) (fontMetrics.descent - fontMetrics.ascent)
写字时的baseline的计算方法在这就不写了
对自己以后编程逻辑 比较有启发的代码:
检查当前所累加的view的宽度是否超过了边界,如果超过,则换行,同时为了在onlayout方法中确定什么时候换行,用了List<List<View>>的形式,用两个foreach()语句即可实现。
onMeasure();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
outList.clear();
List<View> innerList = new ArrayList<>();
outList.add(innerList);
int width = 0;
int Maxwidth = 0;
int layoutWith = MeasureSpec.getSize(widthMeasureSpec);
screeWidth = layoutWith;
int childCount = getChildCount();
for(int i = 0;i<childCount;i++){
View childView = getChildAt(i);
measureChild(childView,widthMeasureSpec,heightMeasureSpec);
int childWidth = childView.getMeasuredWidth();
width +=childWidth;
if(width >layoutWith){
int currentMax = width - childView.getMeasuredWidth();
Maxwidth = Math.max(Maxwidth,currentMax);
width = childView.getMeasuredWidth();
height += childView.getMeasuredHeight();
innerList = new ArrayList<>();
outList.add(innerList);
secondLostControl = false;
}else if(secondLostControl){
height = childView.getMeasuredHeight();
}
innerList.add(childView);
setMeasuredDimension(Maxwidth,height);
}
}
onLayout():
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int measureWidth = 0;
int getwidth = 0;
for(View childView : outList.get(1)){
measureWidth += childView.getMeasuredWidth();
getwidth += childView.getWidth();
}
Log.d(TAG, "getMeasureWidth: "+measureWidth +"getWidth: "+getwidth+"screeWidth"+screeWidth);
//以上测试代码
int orginBottom = outList.get(0).get(0).getMeasuredHeight();
int left = 0,top = 0,bottom = orginBottom,right = 0;
for (List<View> viewList:outList){
for(View childView:viewList){
right += childView.getMeasuredWidth();
childView.layout(left,top,right,bottom);
left += childView.getMeasuredWidth();
}
bottom += orginBottom;
top += orginBottom;
left =0;
right = 0;
}
}