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

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

    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. [数据库技术] MySQL中英文混合排序 4 个条目
  2. [数据结构] 图的定义 1 个条目
  3. [移动开发] Android 开发调试工具 ADB 3 个条目
  4. [移动开发] Android根基概念Context 8 个条目
  5. [搜索引擎优化] 百度搜索引擎优化指南 3 个条目
  6. [Python程序设计] Django数据库模型 6 个条目
  7. [Python程序设计] urls.py设置技巧 8 个条目
  8. [智力开发与知识管理] 超越整体性学习 5 个条目
  9. [移动开发] ListView 使用相关问题集 1 个条目
  10. [PHP程序设计] 声明式编程范式 12 个条目
  11. [计算机算法] 两数交换的各种算法细节 2 个条目
  12. [PHP程序设计] PHP与函数式编程 1 个条目
窗口 -- [博客]