为什么在invalidate()之后没有调用onDraw?

dar*_*ord 47 android

我在stackoverflow上发现了很多帖子,但我仍然无法解决我的问题.这是我的代码片段:

public class MyView extends RelativeLayout {

Button b1;
Button b2;
Context sContext;
public static int i = 0;
private int w = 400;
private int h = 400;
private int w2 = 100;
private int h2 = 100;

public MyView(Context context) {
    super(context);
    sContext = context;
    init();
}

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
    sContext = context;
    init();
}

private void init() {
    b1 = new Button(sContext);
    addView(b1);
    b1.setBackgroundColor(Color.YELLOW);

    b1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (w >= 600) {
                MyView.this.setBackgroundColor(Color.GREEN);
                //b1.setBackgroundColor(Color.RED);
            } else {
                MyView.this.setX(100);
            }

            MyView.this.invalidate();
            w += 100;
            w2 += 20;
        }

    });
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //b1.setBackgroundColor(Color.RED);
    Toast.makeText(sContext, ""+i, Toast.LENGTH_SHORT).show();
    ++i;
}
}
Run Code Online (Sandbox Code Playgroud)

你能解释一下为什么在按b1的前三次没有调用onDraw吗?因为我每次按b1都会调用invalidate.非常感谢你!

小智 93

默认情况下,所有ViewGroup子类都不调用它们的onDraw方法,您应该通过调用link来启用它setWillNotDraw(false)


Rag*_*dan 20

借用链接@

Android自定义布局 - onDraw()永远不会被调用

尝试下面的工作

1.如果您正在扩展ViewGroup(在您的情况下为a RelativeLayout),则应覆盖dispatchDraw()而不是onDraw().

关于这个话题的讨论@

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/oLccWfszuUo

protected void dispatchDraw (Canvas canvas)

通过绘制调用来绘制子视图.这可以被派生类覆盖,以便在绘制子节点之前获得控制(但是在绘制了它自己的视图之后).

参数

画布用于绘制视图的画布

public class Hello  extends Activity {

    private MyView myView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

                super.onCreate(savedInstanceState);
                Log.e("hello", "hello");
                this.myView = new MyView(this);
                setContentView(this.myView);

    }
     public class MyView extends RelativeLayout
       {

      private Paint myPaint = new Paint();
      private int[] numbers;
      public MyView(Context paramContext)
      {
        super(paramContext);
        Log.e("MyView", "MyView");
        setFocusable(true);
        setBackgroundResource(R.drawable.ic_launcher);
      }
      @Override
      protected void dispatchDraw(Canvas canvas){         

            super.dispatchDraw(canvas);     
            Log.i("...............","drawing");   
        }

  }
}
Run Code Online (Sandbox Code Playgroud)

2.如果你onDraw在构造函数调用中覆盖,setWillNotDraw(false)那么它应该工作.

http://developer.android.com/reference/android/view/View.html#setWillNotDraw(boolean)

public MyView(Context context) {
super(context);
sContext = context;
init();
setWillNotDraw(false); 
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*gue 13

您需要调用setWillNotDraw(false);以便调用onDraw方法:

private void init() {
  setWillNotDraw(false);
  ...
}
Run Code Online (Sandbox Code Playgroud)

  • 不客气,请不要忘记检查答案按钮:) (2认同)