• 从源码角度去理解layout_weight的机理

    阅读源码
    服务器君一共花费 23.311 ms 进行了 4 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    layout_weight 表示 LinearLayout 中额外空间的划分(可能扩大应用 layout_weight 前的大小也可能缩小)。

    为了更清晰地理解,这里抽取一部分源码来阅读。

    //Either expand children with weight to take up available space or
    // shrink them if they extend beyond our current bounds
    int delta = widthSize - mTotalLength;
    if (delta != 0 && totalWeight > 0.0f) {
        float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
        for (int i = 0; i < count; ++i) {
            final View child = getVirtualChildAt(i);
    
            if (child == null || child.getVisibility() == View.GONE) {
                continue;
            }
            
            final LinearLayout.LayoutParams lp =
                    (LinearLayout.LayoutParams) child.getLayoutParams();
    
            float childExtra = lp.weight;
            if (childExtra > 0) {
                int share = (int) (childExtra * delta / weightSum);
           weightSum -= childExtra;
            delta  -= share;
                int childWidth = child.getMeasuredWidth() + share;
                if (childWidth < 0) {
                    childWidth = 0;
                }
            }
        }
    }
    

    变量含义:

    • widthSize: LinearLayout的宽度
    • mTotalLength: 所有子View的宽度的和(还没用考虑layout_weight)
    • totalWeight: 所有子View的layout_weight的和
    • mWeihtSUm: LinearLayout的android:weightSum属性

    首先计算出额外空间(可以为负)如果额外空间不为0并且有子View的 layout_weight 不为0的话按layout_weight分配额外空间:

    int delta = widthSize - mTotalLength;
    if (delta != 0 && totalWeight > 0.0f) {
      ...
    }
    

    如果LinearLayout设置了weightSum则覆盖子View的layout_weight的和:

    float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
    

    然后遍历LinearLayout的子元素,如果不为null且Visibility不为GONE的话,取得它的LayoutParams,如果它的layout_weight大于0,根据weightSum与它的weight计算出分配给它的额外空间:

    if (childExtra > 0) {
        int share = (int) (childExtra * delta / weightSum);
       weightSum -= childExtra;
       delta -= share;
    
        int childWidth = child.getMeasuredWidth() + share;
        if (childWidth < 0) {
            childWidth = 0;
        }
    }
    

    看一下源码,对 layout_weight 的运行机制就会清晰很多。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [数据库技术] 数据库范式篇 5 个条目
  2. [Python程序设计] urls.py设置技巧 8 个条目
  3. [移动开发] 使用support-v7 ActionBar前的那些坑 3 个条目
  4. [软件工程与项目管理] 浏览器与CSS渲染技巧 2 个条目
  5. [软件工程与项目管理] 开始了解Git 5 个条目
  6. [PHP程序设计] PHP中的Hash算法 3 个条目
  7. [PHP程序设计] htaccess 设置技巧 6 个条目
  8. [Python程序设计] Python语言概述 6 个条目
  9. [Python程序设计] Django 入门知识浅介 10 个条目
  10. [PHP程序设计] 对输入文件类型的检测 1 个条目
  11. [PHP程序设计] PHP里的引用 5 个条目
  12. [运维管理] 防火墙原理与应用 5 个条目
窗口 -- [八点]