自定义ViewGroup不正确onLayout

时间:2012-03-01 20:45:27

标签: android android-layout android-custom-view viewgroup

我正在尝试编写自己的布局类。但是我在onLayout上遇到了麻烦。如果我扩展LinearLayout并让它执行onLayout并且我在onMeasure中调用super.onMeasure(),那么一切正常。但它不能扩展ViewGroup。显示的是第一个最左边的孩子被正确渲染但其余的没有显示或者尺寸不合适。

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;

class ManualPanel extends ViewGroup
{
    private int totalDivs;
    private int[] sizesArr;

    public ManualPanel(final Context context)
    {
        this(context, null);
    }

    public ManualPanel(final Context context, final AttributeSet attrs)
    {
        super(context, attrs);

        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ManualPanel);

        final String[] sizeStr = a.getString(R.styleable.ManualPanel_sizes).split("/");
        final String[] fracArr = sizeStr[0].split(",");
        a.recycle();

        int sum = 0;
        sizesArr = new int[fracArr.length];
        for (int i = 0; i < sizesArr.length; i++) {
            sizesArr[i] = Integer.valueOf(fracArr[i]);
            sum += sizesArr[i];
        }
        totalDivs = Math.max(sum, Integer.valueOf(sizeStr[1]));
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
    {
        final int children = getChildCount();
        final int totalWidth = MeasureSpec.getSize(widthMeasureSpec);
        final int totalHeight = MeasureSpec.getSize(heightMeasureSpec);

        totalDivs = Math.max(totalDivs, children);

        final int[] arr = IntArray.copyOf(sizesArr, children);
        final int width[] = new int[children];
        int sum = 0;

        for (int i = 0; i < children; i++) {
            width[i] = (arr[i] * totalWidth) / totalDivs;
            sum += width[i];
        }
        for (int i = 0, diff = totalWidth - sum; diff > 0; i = ++i % children) {
            width[i]++;
            diff--;
        }
        for (int i = 0; i < children; i++) {
            final View view = getChildAt(i);
            final LayoutParams lp = view.getLayoutParams();

            lp.width = width[i];
            view.setLayoutParams(lp);
            view.measure(MeasureSpec.EXACTLY | lp.width, MeasureSpec.EXACTLY | totalHeight);
        //  view.measure(MeasureSpec.AT_MOST | lp.width, MeasureSpec.AT_MOST | totalHeight);
        }
        setMeasuredDimension(totalWidth, totalHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        final int children = getChildCount(), height = getMeasuredHeight();
        for (int i = 0; i < children; i++) {
            final View view = getChildAt(i);

            if (view.getVisibility() != View.VISIBLE)
                continue;

            final int width = view.getMeasuredWidth();
            view.layout(l, 0, left + width, height);
            l += width;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

ViewGroup不知道如何放置孩子。或者如何绘制它们。你必须自己做。

答案 1 :(得分:0)

我还没有尝试过你的布局。但这就是我所看到的。 看看你的专栏

view.layout(l, 0, left + width, height);

您的left变量似乎总是等于零,因为您不会在循环内更改它。