51

我在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;
}
}

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

4

5 回答 5

98

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

于 2013-07-11T14:10:22.793 回答
22

借用链接@

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

试试下面它的工作原理

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

话题讨论@

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

protected void dispatchDraw (Canvas canvas)

由 draw 调用以绘制子视图。这可能会被派生类覆盖,以便在绘制其子级之前(但在绘制其自己的视图之后)获得控制

参数

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");   
        }

  }
}

onDraw2.如果您在构造函数调用中覆盖,setWillNotDraw(false)那么它应该可以工作。

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

public MyView(Context context) {
super(context);
sContext = context;
init();
setWillNotDraw(false); 
}
于 2013-07-11T14:24:12.913 回答
14

您需要调用setWillNotDraw(false);才能调用 onDraw 方法:

private void init() {
  setWillNotDraw(false);
  ...
}
于 2013-07-11T14:06:17.027 回答
0

我没有使用 4.1 Jelly Bean API 16 在 C# 中调用 OnDraw。我从使用 API 16 SDK 编译切换到使用 7.1 Nougat SDK 编译。它彻底解决了问题。我仍然有 API 16 的 manifest min sdk,它在我的 Jelly Beam avd 中运行良好。

于 2017-12-24T15:41:38.460 回答
0

在我的情况下onDraw没有调用,因为我0以视图的宽度或高度返回。

于 2020-12-20T14:56:14.583 回答