TypedArray中的getDrawable()方法返回null?

9

我在我的自定义View中使用TypedArray.getDrawable()时遇到了奇怪的问题。为了简单起见,这里是一个显示相同问题的微不足道的测试项目:

TestView.java

package com.example.testing;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

public class TestView extends View {

    private Drawable mDrawable;

    public TestView(Context context) {
        this(context, null);
    }

    public TestView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TestView, defStyle, 0);
        try {
            Drawable d = a.getDrawable(R.styleable.TestView_testDrawable);
            if (d != null) {
                setDrawable(d);
            }
        } finally {
            a.recycle();
        }
    }

    private void setDrawable(Drawable d) {
        mDrawable = d;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (mDrawable != null) {
            mDrawable.draw(canvas);
        }
    }
}

res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>    
    <declare-styleable name="TestView">
        <attr name="testDrawable" format="reference|color" />
    </declare-styleable>
</resources>

res/layout/main_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res/com.example.testing"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

     <com.example.testing.TestView
         android:id="@+id/testView1"
         android:layout_width="match_parent"
         android:layout_height="100dp"
         custom:testDrawable="#ff0099" />
</LinearLayout>

我在布局编辑器和实际设备上都看不到可爱的粉色矩形,我不明白出了什么问题。

2个回答

1

我检查了你的代码,mDrawable 不是 null,但它的大小是 -1 x -1。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    mDrawable.setBounds(0, 0, View.MeasureSpec.getSize(widthMeasureSpec), View.MeasureSpec.getSize(heightMeasureSpec));
}

这对我来说很管用。我不知道这是否符合您的要求,但或许这是一个起点。


或者如果您想包括填充: this.mDrawable.setBounds(this.getPaddingLeft(), this.getPaddingTop(), View.MeasureSpec.getSize(widthMeasureSpec) - this.getPaddingRight(), View.MeasureSpec.getSize(heightMeasureSpec) - this.getPaddingBottom()); - ankri.de
确实,为可绘制对象设置边界就是答案。我也刚刚发现了这一点。 - Karakuri
再看一遍,这样可能更好:mDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); - Karakuri

0

这是我之前处理类似情况的方式(我稍微修改了一下以适应你的代码):

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TestView, defStyle, 0);
TypedValue value = a.peekValue(R.styleable.TestView_testDrawable);
if (value != null) {
    if (value.type == TypedValue.TYPE_REFERENCE ||
        value.type == TypedValue.TYPE_STRING) {
        Drawable d = a.getDrawable(R.styleable.TestView_testDrawable);
        if (d != null) {
            setDrawable(d);
        }
    }
    else
    if (value.type == TypedValue.TYPE_INT_COLOR_ARGB8 ||
        value.type == TypedValue.TYPE_INT_COLOR_ARGB4 ||
        value.type == TypedValue.TYPE_INT_COLOR_RGB8  ||
        value.type == TypedValue.TYPE_INT_COLOR_RGB4) {
        Drawable d = new PaintDrawable(a.getColor(R.styleable.TestView_testDrawable, 0xFF000000));
        if (d != null) {
            setDrawable(d);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接