Подтвердить что ты не робот

Почему onDraw не вызывается после invalidate()?

Я нашел много сообщений в 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;
}
}

Не могли бы вы объяснить, почему onDraw не вызывается в первые три раза, я нажимаю b1? Потому что я вызывал invalidate каждый раз, когда нажимаю b1. Большое вам спасибо!

4b9b3361

Ответ 1

По умолчанию все подклассы ViewGroup не вызывают их метод onDraw, вы должны включить его, вызвав setWillNotDraw(false) ссылка

Ответ 2

Заимствование по ссылке @

Пользовательский макет 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");   
        }

  }
}

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

Ответ 3

Вам нужно вызвать setWillNotDraw(false); для вызова метода onDraw:

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

Ответ 4

У меня был OnDraw, не вызываемый в С#, с использованием 4.1 Jelly Bean API 16. Я перешел от компиляции с API 16 SDK к компиляции с 7.1 Nougat SDK. Он полностью решил проблему. У меня все еще есть манифест min sdk API 16, и он отлично работает в моем Jelly Beam avd.