0

已解决:以下解决方案作为答案。

我有一个带有 TransitionDrawable 的自定义视图,当我在 onDraw() 方法中绘制它时,它会自动缩放以填充整个父布局,即使它在 xml 中设置为 wrap_content。图片在mdpi和hdpi中,我的测试设备(三星galaxy s)我认为它只不过是hdpi。

package com.adyrsoft.pronunciationtrainer;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class RecordButton extends View {
    private static final String TAG = "RecordButton";
    private TransitionDrawable mDrawable;
    private boolean mActivated;

    private OnClickListener mOnClickListenerInternal = new OnClickListener() {

        @Override
        public void onClick(View v) {
            toggleState();
            if(mOnClickListener != null) {
                mOnClickListener.onClick(v);
            }
        }

    };

    private OnClickListener mOnClickListener = null;

    public RecordButton(Context context) {
        super(context);
        init();
    }

    public RecordButton(Context context, AttributeSet attrib) {
        super(context, attrib);
        init();
    }

    public RecordButton(Context context, AttributeSet attrib, int defStyle) {
        super(context, attrib, defStyle);
        init();
    }

    public void setState(boolean activated) { 
        mActivated = activated;
        if(mActivated){
            mDrawable.startTransition(300);
        }
        else {
            mDrawable.reverseTransition(300);
        }
    }

    public void toggleState() {
        if(mActivated) {
            setState(false);
        }
        else {
            setState(true);
        }
    }

    @SuppressWarnings("deprecation")
    private void init() {
        mActivated = false;
        mDrawable = (TransitionDrawable) getResources().getDrawable(R.drawable.btnrecord);

        Log.d(TAG, "Drawable intrinsic width and height are: " + 
                Integer.toString(mDrawable.getIntrinsicWidth()) + " " +
                Integer.toString(mDrawable.getIntrinsicHeight()));

        mDrawable.setBounds(0,0,mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());



        Log.d(TAG, "The bounds for the button are: "+mDrawable.getBounds().flattenToString());
        super.setBackgroundDrawable(mDrawable);
        setClickable(true);
        super.setOnClickListener(mOnClickListenerInternal);
        invalidate();
    }

    public void setOnClickListener(View.OnClickListener listener) {
        mOnClickListener = listener;
    }

    protected void onDraw (Canvas canvas) {
        super.onDraw(canvas);
    }

}

我究竟做错了什么?谢谢。

4

1 回答 1

0

经过数小时试图了解我应该如何在自定义视图中使用可绘制对象以便以其原始大小显示之后,我已经想出了如何做到这一点。

首先,我不知道但必须做的几件事是:

  1. 当使用 View 作为父级时,背景 drawable 应该留给父类来绘制。如果没有,则无法看到图片之间的 TransitionDrawable 褪色。
  2. 只有当我要在背景可绘制对象上绘制时,我才应该覆盖 onDraw() 并在那里进行绘制。
  3. 最后但同样重要的是我应该重写 onMeasure() 来指定视图的大小。如果我不这样做,它将填充父布局中的所有可用空间,就像发生在我身上一样。

我已经使用 setBackgroundDrawable() 将 TransitionDrawable 传递给了父类,并且由于我没有在后台绘制,因此我删除了 onDraw() 方法。我还用一个快速而肮脏的解决方案实现了 onMeasure(),指定了我正在绘制的图片的大小。

这是最终结果:

public class RecordButton extends View {
    private static final String TAG = "RecordButton";
    private static final int DESIRED_WIDTH = 180;
    private static final int DESIRED_HEIGHT = 66;
    private TransitionDrawable mDrawable;
    private Rect mViewRect;
    private boolean mActivated;

    private OnClickListener mOnClickListenerInternal = new OnClickListener() {

        @Override
        public void onClick(View v) {
            toggleState();
            if(mOnClickListener != null) {
                mOnClickListener.onClick(v);
            }
        }

    };

    private OnClickListener mOnClickListener = null;

    public RecordButton(Context context) {
        this(context, null, 0);

    }

    public RecordButton(Context context, AttributeSet attrib) {
        this(context, attrib, 0);
    }

    public RecordButton(Context context, AttributeSet attrib, int defStyle) {
        super(context, attrib, defStyle);
        init();
    }

    public void setState(boolean activated) { 
        mActivated = activated;
        if(mActivated){
            mDrawable.startTransition(300);
        }
        else {
            mDrawable.reverseTransition(300);
        }
    }

    public void toggleState() {
        if(mActivated) {
            setState(false);
        }
        else {
            setState(true);
        }
    }

    @SuppressWarnings("deprecation")
    private void init() {
        mActivated = false;
        mDrawable = (TransitionDrawable) getResources().getDrawable(R.drawable.btnrecord);

        setBackgroundDrawable(mDrawable);

        setClickable(true);
        super.setOnClickListener(mOnClickListenerInternal);
        invalidate();
    }

    public void setOnClickListener(View.OnClickListener listener) {
        mOnClickListener = listener;
    }

    @Override
    protected void onMeasure(int m, int n) {
        setMeasuredDimension(DESIRED_WIDTH, DESIRED_HEIGHT);
    }

}
于 2013-09-04T23:11:21.373 回答