onDraw()メソッドが実行されない解決方法(setWillNotDraw)について

9103 ワード

一.引用:
プロジェクトの必要性から、Viewが提供するonDraw()メソッドを複写するために、直接または間接的にViewを継承するクラスを新規または間接的に作成する必要がある場合がありますが、結果が得られない場合があります.今日はonDraw()メソッドが実行されない解決方法についてお話しします.また、onDraw()メソッドにブレークポイントやlogを設定しているかもしれませんが、プログラムがonDraw()メソッドを実行していないことに気づきました.では、Viewのクラスを直接または間接的に継承するコンストラクション関数に次の文を追加する必要があります.
        setWillNotDraw(false);

二.説明:
では、この文を加える役割は何ですか.まずAPIを見てください.
  If this view doesn't do any drawing on its own, set this flag to allow further optimizations. By default, this flag is not set on View, but could be set on some View subclasses such as ViewGroup. Typically, if you override onDraw(Canvas) you should clear this flag.

私の外国语の基础はとても良くなくて、简単に翻訳して、もし翻訳のよくないならば、レンガを投げないでください、私の言叶を缲り返します:想像して、想像がなくて、世界はどんなことができます.へへへ:
現在のviewで描画操作を行わない場合は、将来のより良い必要性のためにこのタグを設定する必要があります.デフォルトでは、このタグはViewでは設定されていません.しかし、Viewのような一部のサブクラス、例えばView Groupは設定できます.典型的には、onDraw(Canvas)メソッドを複写した場合、このタグをクリアする必要があります.
ちょうど、私たちが実現したのはViewのサブクラスです.LinearLayoutです.もちろん、他のサブクラスを継承することもできます.
AbsoluteLayout,AdapterView,FrameLayout,LinearLayout,RelativeLayout,SlidingDrawer,サブクラスは言わないで、自分でドキュメントを調べることができます.
次のように、継承クラスのコンストラクション関数にこの文を配置します.
public classBackgroundLayout extendsLinearLayout {  

        publicBackgroundLayout(Context context, intposition) {  

                super(context);  

                // TODOAuto-generated constructor stub  

                setWillNotDraw(false);  

        }  

        @Override  

        protected voidonDraw(Canvas canvas) {  

                // TODOAuto-generated method stub  

                super.onDraw(canvas);  

                }  

        }  

}  

三、見方を広げる:
eoeandroidのLittleのこの文についての見方は次のとおりです.
     view    ,          view,  ondraw()           false,             。

ここで引用します.
                    :setWillNotDraw(false);         ?    onDraw()         ,           false.

四、ForegroundImageView:
package com.example.android.unsplash.ui;


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.ViewOutlineProvider;
import android.widget.ImageView;

import com.example.android.unsplash.R;


public class ForegroundImageView extends ImageView {

    private Drawable foreground;

    public ForegroundImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundView);

        final Drawable d = a.getDrawable(R.styleable.ForegroundView_android_foreground);
        if (d != null) {
            setForeground(d);
        }
        a.recycle();
        setOutlineProvider(ViewOutlineProvider.BOUNDS);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (foreground != null) {
            foreground.setBounds(0, 0, w, h);
        }
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }

    @Override
    protected boolean verifyDrawable(Drawable who) {
        return super.verifyDrawable(who) || (who == foreground);
    }

    @Override
    public void jumpDrawablesToCurrentState() {
        super.jumpDrawablesToCurrentState();
        if (foreground != null) foreground.jumpToCurrentState();
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        if (foreground != null && foreground.isStateful()) {
            foreground.setState(getDrawableState());
        }
    }

    /**
     * Returns the drawable used as the foreground of this view. The
     * foreground drawable, if non-null, is always drawn on top of the children.
     *
     * @return A Drawable or null if no foreground was set.
     */
    public Drawable getForeground() {
        return foreground;
    }

    /**
     * Supply a Drawable that is to be rendered on top of the contents of this ImageView
     *
     * @param drawable The Drawable to be drawn on top of the ImageView
     */
    public void setForeground(Drawable drawable) {
        if (foreground != drawable) {
            if (foreground != null) {
                foreground.setCallback(null);
                unscheduleDrawable(foreground);
            }

            foreground = drawable;

            if (foreground != null) {
                foreground.setBounds(0, 0, getWidth(), getHeight());
                setWillNotDraw(false);
                foreground.setCallback(this);
                if (foreground.isStateful()) {
                    foreground.setState(getDrawableState());
                }
            } else {
                setWillNotDraw(true);
            }
            invalidate();
        }
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        if (foreground != null) {
            foreground.draw(canvas);
        }
    }

    @Override
    public void drawableHotspotChanged(float x, float y) {
        super.drawableHotspotChanged(x, y);
        if (foreground != null) {
            foreground.setHotspot(x, y);
        }
    }
}