Android自定义View实践之ViewGroup

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

效果图

screen_shot.png

效果分析

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

实现方式

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

  • 由于有优先完整显示的子View,所以第一次遍历所有子View找到需要优先显示的子View进行测量,直接调用ViewGoup中的measureChildWithMargins获取测量宽高,如下:
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();
    }
}
  • 再次遍历测量未优先显示的子View,以剩余宽高来作为最大宽高来测量,具体代码如下:
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());
}
  • 经过以上的子View测量,我们能够很容易得到该ViewGroup需要的宽高,即上述中的width和height,调用setMeasuredDimension()方法设置ViewGroup的宽高。
setMeasuredDimension(getDefaultSize(width, widthMeasureSpec), getDefaultSize(height, heightMeasureSpec));

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

  • 没啥说的,唯一需要注意的是child.layout()传入的是相对与改父View的相对坐标,直接遍历所有子View,调用子View的onLayout(int left,int top,int right,int bottom)方法,为了让margin生效,需要加上margin,代码如下:
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>

详细代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272