0

我有一个ViewAnimator包含两个子视图的。ViewAnimator无论哪个孩子当前处于活动状态,我都希望成为第一个孩子的大小。这可以通过一些配置实现还是我必须实现自己的子类和覆盖onMeasure等?

4

1 回答 1

1

我最终通过将布局的尺寸扩展ViewAnimator、覆盖和设置为第一个孩子的尺寸来解决这个问题。onMeasure这就是我想出的。这基本上是对FrameLayout.onMeasure方法的一个小修改。

/**
 * Overrides the default {@link android.widget.FrameLayout#onMeasure(int, int)}
 * behavior to allow a main child to be defined which determines the size of the
 * layout. By default, the max size of all children is used as the layout size.
 */
public class SizePinnedViewAnimator extends ViewAnimator {
    private final int mainChildIndex;

    @SuppressWarnings("UnusedDeclaration")
    public SizePinnedViewAnimator(final Context context) {
        super(context);
        mainChildIndex = 0;
    }

    @SuppressWarnings("UnusedDeclaration")
    public SizePinnedViewAnimator(final Context context, final AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(
                attrs,
                R.styleable.SizePinnedViewAnimator);
        mainChildIndex = a.getInt(R.styleable.SizePinnedViewAnimator_mainChild, 0);
        a.recycle();
    }

    /**
     * {@inheritDoc}
     *
     * Copied from {@link android.widget.FrameLayout#onMeasure(int, int)}
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int count = getChildCount();

        View mainChild = getChildAt(mainChildIndex);
        if(mainChild == null) {
            throw new IllegalStateException("No child at index " + mainChildIndex);
        }

        measureChildWithMargins(mainChild, widthMeasureSpec, 0, heightMeasureSpec, 0);

        int maxHeight = mainChild.getMeasuredHeight();
        int maxWidth = mainChild.getMeasuredWidth();

        widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);

        // Find rightmost and bottommost child
        for (int i = 0; i < count; i++) {
            if(i == mainChildIndex) continue;

            final View child = getChildAt(i);
            if (getConsiderGoneChildrenWhenMeasuring() || child.getVisibility() != GONE) {
                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
            }
        }

        // Don't have access to the foreground padding numbers, but we're not
        // using a foreground drawable anyway, so ignore it.

        // Account for padding too
        maxWidth += getPaddingLeft() + getPaddingRight();
        maxHeight += getPaddingTop() + getPaddingBottom();

        // Check against our minimum height and width
        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

        setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
                resolveSize(maxHeight, heightMeasureSpec));
    }
}

并且在中定义的属性res/values/attrs.xml

<declare-styleable name="SizePinnedViewAnimator">
    <attr name="mainChild" format="integer" />
</declare-styleable>
于 2012-08-22T13:59:12.917 回答