无法正确测量自定义视图?

时间:2011-08-03 12:48:08

标签: android custom-controls

我正在编写一个自定义View对象,但我似乎无法正确测量它。通过查看View source code,我认为调用setMinimumHeight()setMinimumWidth()就足够了(这就是我所需要的,父布局应该遵循的最小尺寸)。这是我的代码:

public class MonthView extends View {

    private final int minCellSize = 24;

    public MonthView(Context context) {
        super(context);
    }

    public MonthView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MonthView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final float scale = getContext().getResources().getDisplayMetrics().density;
        setMinimumHeight((int) (minCellSize * scale * 6));
        setMinimumWidth((int) (minCellSize * scale * 7));
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.RED);
    }

}

非常简单。然后我将其嵌入LinearLayout,类似这样:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <com.foghina.adtp.MonthView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:text="I am below the monthview!"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

但是,MonthView占据整个屏幕,TextView不可见。如何在View使用wrap_content时正确编写{{1}}以使其具有最小高度/宽度?​​

2 个答案:

答案 0 :(得分:1)

我最终想通了。我不得不编写自己的View.getDefaultSize()版本,这只是略有不同。这是我使用它的方式:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final float scale = getContext().getResources().getDisplayMetrics().density;
    setMeasuredDimension(getSize((int) (minCellSize * scale * 7), widthMeasureSpec),
            getSize((int) (minCellSize * scale * 6), heightMeasureSpec));
}

private static int getSize(int size, int measureSpec) {
    int result = size;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize =  MeasureSpec.getSize(measureSpec);

    switch (specMode) {
    case MeasureSpec.UNSPECIFIED:
        result = size;
        break;
    case MeasureSpec.AT_MOST:
        result = size < specSize ? size : specSize;
        break;
    case MeasureSpec.EXACTLY:
        result = specSize;
        break;
    }

    return result;
}

非常讨厌。我不明白为什么默认View.getDefaultSize()不能像那样工作。

答案 1 :(得分:0)

我认为你必须使用setMeasureDimension()