Skip to content

Instantly share code, notes, and snippets.

@pythoncat1024
Created December 22, 2018 19:36
Show Gist options
  • Save pythoncat1024/a2ce8a54a00171320358b6eeec3dee6a to your computer and use it in GitHub Desktop.
Save pythoncat1024/a2ce8a54a00171320358b6eeec3dee6a to your computer and use it in GitHub Desktop.
自定义 viewGroup 在 onMeasure 以及 onLayout 的时候,可以知道 itemView 是否设置了 match_parent 属性
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int ws = MeasureSpec.getSize(widthMeasureSpec);
int wm = MeasureSpec.getMode(widthMeasureSpec);
int hs = MeasureSpec.getSize(heightMeasureSpec);
int hm = MeasureSpec.getMode(heightMeasureSpec);
boolean needMaxWidth = false;
boolean needMaxHeight = false;
this.maxWidth = ws;
// LogUtils.i("default wh: " + ws + " , " + hs);
int count = getChildCount();
int width = 0;
int height = 0;
int lineWidth = 0; // 预先的 行宽
int lineHeight = 0; // 预先的 行宽
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child == null || child.getVisibility() == GONE) {
continue;
}
// 测量 child 宽高 --- start
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
int measuredWidth = child.getMeasuredWidth();
int measuredHeight = child.getMeasuredHeight();
// 测量 child 宽高 --- end
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
LogUtils.e("lp====+==" + lp.width + " ### " + lp.height);
if (lp.width == LayoutParams.MATCH_PARENT) {
needMaxWidth = true;
}
if (lp.height == LayoutParams.MATCH_PARENT) {
needMaxHeight = true;
}
int itemW = measuredWidth + lp.leftMargin + lp.rightMargin;
int itemH = measuredHeight + lp.topMargin + lp.bottomMargin;
if (lineWidth + itemW > ws - getPaddingLeft() - getPaddingRight()) {
// 换行 ,先记录换行之前的数据
width = Math.max(width, lineWidth); // 记录的是上一行的数据
height += lineHeight; // 记录的是上一行的数据
// 换行了
lineHeight = itemH;
lineWidth = itemW;
} else {
// 不换行
lineHeight = Math.max(lineHeight, itemH);
lineWidth += itemW;
}
if (i == count - 1) {
// 最后一个 view , 记录这一行的数据
width = Math.max(width, lineWidth); // 记录的是这一行的数据
height += lineHeight; // 记录这一行的数据
}
}
int finalW = wm == MeasureSpec.EXACTLY || needMaxWidth ? ws : width + getPaddingLeft() + getPaddingRight();
int finalH = hm == MeasureSpec.EXACTLY || needMaxHeight ? hs : height + getPaddingTop() + getPaddingBottom();
LogUtils.e("need? " + needMaxWidth + " ,, " + needMaxHeight);
// setMeasuredDimension(ws, hs); // 设置成 fill_parent 了
LogUtils.e("size==" + finalW + " ,, " + ws);
setMeasuredDimension(finalW, finalH);
}
@pythoncat1024
Copy link
Author

pythoncat1024 commented Dec 22, 2018

判断逻辑:

onMeasureonLayout 里面都可以:

            lp = child.getLayoutParams();
            if (lp.width == LayoutParams.MATCH_PARENT) {
                needMaxWidth = true;
            }

这种判断的意义就是,实现类似RelativeLayout的这种效果:当自己本身设置为 wrap_content 的时候,而 item 设置了match_parent , 然后导致自己事实上也变成match_parent 的效果。

    <RelativeLayout
        android:visibility="visible"
        android:background="#000"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:textColor="#fff"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/border_drawable"
            android:text="@string/add_calendar_event" />
<!-- 导致 RelativeLayout 实际上是 match_parent 显示, TextView 本身也是 match_parent  -->
    </RelativeLayout>

而,如果外部换成 LinearLayout就会让 LinearLayout以及 TextView都变成 wrap_content状态显示

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment