Android: расширение виджетов и границ холста - расширение кнопки - PullRequest
0 голосов
/ 01 сентября 2011

Все, что я хотел, это создать кнопку, которая в некоторых случаях будет содержать изображение 'v', чтобы отметить его активность.на самом деле это не флажок, так как не каждый раз, когда вы нажимаете кнопку, она меняет свое состояние.

Но идея такова.Мне нужна простая кнопка, и у меня есть другое маленькое изображение 'v', которое, если я использую метод toggle () для этой кнопки, кнопка будет достаточно расширена, так что изображение 'v' может легко втиснуться в ее верхний правый угол.

это мой код:

public class ButtonWithV extends Button {
    private Drawable mVImageDrawable;
    private int mImageWidth;
    private boolean mIsMarked;

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

    public ButtonWithV(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.ButtonWithVStyle);
    }

    public ButtonWithV(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mImageWidth = 0;
        TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.ButtonWithV, defStyle, 0);
        Drawable d = a.getDrawable(R.styleable.ButtonWithV_button_v_drawable);
        if( d != null){
            setVImageDrawable(d);
        }
//      setPadding(getPaddingLeft(), getPaddingTop(),
//              getPaddingRight(), getPaddingBottom());
        mIsMarked = false;
    }

    public void setMarked(boolean marked){
        if( marked != mIsMarked){
            mIsMarked = marked;
            requestLayout();
//          invalidate();
        }
    }

    private void setVImageDrawable(Drawable d) {
        mVImageDrawable = d;
        mImageWidth = mVImageDrawable.getIntrinsicWidth();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Rect temp = canvas.getClipBounds();
        System.out.println(String.format("top: %d, bottom: %d, left: %d, right: %d",
                temp.top, temp.bottom, temp.left, temp.right));
        super.onDraw(canvas);
        System.out.println(String.format("top: %d, bottom: %d, left: %d, right: %d",
                temp.top, temp.bottom, temp.left, temp.right));

        if( mVImageDrawable != null && mIsMarked){
            Rect bounds = canvas.getClipBounds();
            int right = bounds.right - 5;
            int left = right - mImageWidth;
            int top = bounds.top + 2;
            int bottom = top + mVImageDrawable.getIntrinsicHeight();
            mVImageDrawable.setBounds(left, top, right, bottom);
            mVImageDrawable.draw(canvas);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if( mIsMarked ){
            setMeasuredDimension(getMeasuredWidth() + mImageWidth, getMeasuredHeight());
        }
    }

    public void toggle(){
        setMarked(! mIsMarked );
    }

}

Обратите внимание на -5 и +2 (они не могут оставаться такими, я просто хотел видеть точные цифры).Что я нахожу здесь проблематичным, и, вероятно, будет проблематичным, так это то, что во всех виджетах я не могу использовать виджет getRight (), getLeft () и т.д ...

, поскольку они дают мне РЕАЛЬНОЕ расположение виджета на холсте,однако (onDraw), когда я получаю холст, он обрезается и переводится в (0,0).

Если я правильно понял и хочу узнать самый правый угол виджета, мне нужно получить самый правильный клипугол или измеренная ширина.То же самое касается высоты.

Другая проблема в том, что я понятия не имею, как фон тонет, но я знаю, что, поскольку мне нужно убрать 5 пикселей справа от виджета, чтобы добраться до его точного правильного положения, егоозначает внутренние поля или отступы.

Это не обычные отступы, я проверил.так что это может быть?Как я могу получить, всегда, в том числе, когда пользователь устанавливает отступы и поля в верхнем правом углу относительных координат?Мне нужно рисовать там.

1 Ответ

0 голосов
/ 08 ноября 2011

В конце концов, я использовал отступы, чтобы решить проблему, я просто добавил дополнительные отступы ширины нужной кнопки справа, чтобы я мог нарисовать оверлейное изображение. вот фиксированный снимок кода:

public void setMarked(boolean marked){
        if( marked != mIsMarked){
            mIsMarked = marked;
            requestLayout();
        }
    }


    private void setVImageDrawable(Drawable d) {
        mVImageDrawable = d;
        mImageWidth = mVImageDrawable.getIntrinsicWidth();
    }

    @Override
    public int getCompoundPaddingRight() {
        int orig = super.getCompoundPaddingRight();
        int res = orig;
        if( mIsMarked ){
            res += mImageWidth;
        }
        return res;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if( mVImageDrawable != null && mIsMarked){
            Rect bounds = canvas.getClipBounds();
            int right = bounds.right;
            int left = right - mImageWidth;
            int top = bounds.top;
            int bottom = top + mVImageDrawable.getIntrinsicHeight();
            mVImageDrawable.setBounds(left, top, right, bottom);
            mVImageDrawable.draw(canvas);
        }
    }

    public void toggle(){
        setMarked(! mIsMarked );
    }
...