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

时间:2013-07-11 14:04:37

标签: 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;
}
}

请您解释为什么在按b1时前三次没有调用onDraw?因为我每次按b1都会调用invalidate。非常感谢你!

5 个答案:

答案 0 :(得分:89)

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

来启用它

答案 1 :(得分:19)

借用链接@

Android Custom Layout - onDraw() never gets called

尝试以下工作

1.如果您要扩展ViewGroup(在您的情况下为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");   
        }

  }
}

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

答案 2 :(得分:11)

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

private void init() {
  setWillNotDraw(false);
  ...
}

答案 3 :(得分:0)

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

答案 4 :(得分:0)

就我而言,onDraw 没有被调用,因为我返回了 0 作为视图的宽度或高度。