【问题标题】:Custom View class' onDraw isn't called by InvalidateInvalidate 未调用自定义视图类的 onDraw
【发布时间】:2016-09-10 18:09:47
【问题描述】:

屏幕是白色的,并且从未调用过 onDraw 中的 System.out.println()。

这是我的 activity_main.xml

<foo.packagename.MyView
    android:id="@+id/myView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>

自定义视图类:

public class MyView extends View {

public MyView(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);

    System.out.println("This line is called");

    while (true) {
        invalidate();
    }
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.GREEN);
    System.out.println("This line is never printed");
}

主要活动:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        System.out.println("This line is called");

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View myView = findViewById(R.id.myView);
    }
}

【问题讨论】:

  • 去掉构造函数中的while循环。
  • 修复了它。不过我还是不明白是什么问题
  • 哦,我刚才才注意到你一定在我回复的时候改变了你的评论。是的,下面的答案解释了它。

标签: java android view ondraw android-view-invalidate


【解决方案1】:

invalidate() 不会导致直接调用onDraw()。它只是告诉系统需要在下一个绘图帧上重新绘制视图。否则,在下一个并条框上,系统可以使用之前绘制的内容,因为没有任何改变。换句话说,您的invalidate() 调用和最终的onDraw() 调用是异步的。

此外,在您的构造函数中放置一个无限 while 循环将导致 UI 线程永远不会执行超出该点的代码,因此系统甚至不会完成单个布局传递,并且您的视图将永远不会被绘制一次。不用说,不要这样做

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多