我有ViewAnimator
,其中包含两个子视图。我希望ViewAnimator
的大小与第一个孩子一样大,无论哪个孩子当前活跃。这有可能通过一些配置,还是我必须实现自己的子类并覆盖onMeasure
等?
答案 0 :(得分: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>