编程view

Android自定义View实践之ViewGroup

2019-11-15  本文已影响0人  _罪

Android 自定义ViewGroup实践—让某些子View优先显示完整(压缩其它View)

效果图

screen_shot.png

效果分析

  1. 子View横向排列
  2. 子View竖直居中
  3. 标记为显示完整的View能尽可能地完整显示

实现方式

测量--重写onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法

int widthUsed = 0;
for (int i = 0; i < getChildCount(); i++) {
    View child = getChildAt(i);
    LayoutParams params = (LayoutParams) child.getLayoutParams();
    widthUsed += params.leftMargin;
    widthUsed += params.rightMargin;
    //如果是固定宽度的布局
    if (params.complete) {
        measureChildWithMargins(child, widthMeasureSpec, widthUsed, heightMeasureSpec, 0);
        widthUsed += child.getMeasuredWidth();
    }
}
for (int i = 0; i < getChildCount(); i++) {
    View child = getChildAt(i);
    LayoutParams params = (LayoutParams) child.getLayoutParams();
    widthUsed += params.leftMargin;
    widthUsed += params.rightMargin;
    if (!params.complete) {
        measureChildWithMargins(child, widthMeasureSpec, widthUsed, heightMeasureSpec, 0);
    }
    width += widthUsed;
    width += child.getMeasuredWidth();
    height = Math.max(height, params.topMargin + params.bottomMargin + child.getMeasuredHeight());
}
setMeasuredDimension(getDefaultSize(width, widthMeasureSpec), getDefaultSize(height, heightMeasureSpec));

布局,重写onLayout(boolean changed, int l, int t, int r, int b)方法

int left = 0;
final int layoutHeight = b - t;
for (int i = 0; i < getChildCount(); i++) {
    View child = getChildAt(i);
    //获取测量宽度
    final int width = child.getMeasuredWidth();
    Log.d(TAG, "onLayout: " + width);
    //获取测量高度
    final int height = child.getMeasuredHeght();
    //计算居中的上下偏移量
    final int offset = (layoutHeight - height) / 2;
    MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
    //子View的左侧位置为left+左边距
    left += params.leftMargin;
    child.layout(left, offset, left + width, height + offset);
    Log.d(TAG, "onLayout: [left:" + (l + left) + "  top:" + (t + yOffset) + "  right:" + (l + left + width) + " bottom:" + (b - yOffset));
    //下一个View的左侧位置
    left += width + params.rightMargin;
}

使用方式,在需要尽可能显示完整的View中添加app:complete = "ture",即可

<com.summer.myapplication.widget.NoneCompressLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:singleLine="true"
        android:ellipsize="end" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="固定内容"
        app:complete="true"
        android:layout_marginEnd="10dp"
        android:layout_marginStart="16dp" />

</com.summer.myapplication.widget.NoneCompressLayout>

详细代码

上一篇 下一篇

猜你喜欢

热点阅读