Invalidate 未调用自定义视图类的 onDraw
Posted
技术标签:
【中文标题】Invalidate 未调用自定义视图类的 onDraw【英文标题】:Custom View class' onDraw isn't called by Invalidate 【发布时间】:2016-09-10 18:09:47 【问题描述】:屏幕是白色的,并且从未调用过 onDraw 中的 System.out.println()。
这是我的 activity_main.xml
<foo.packagename.MyView
android:id="@+id/myView"
android:layout_
android:layout_/>
自定义视图类:
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
循环。
修复了它。不过我还是不明白是什么问题
哦,我刚才才注意到你一定在我回复的时候改变了你的评论。是的,下面的答案解释了它。
【参考方案1】:
invalidate()
不会导致直接调用onDraw()
。它只是告诉系统需要在下一个绘图帧上重新绘制视图。否则,在下一个并条框上,系统可以使用之前绘制的内容,因为没有任何改变。换句话说,您的invalidate()
调用和最终的onDraw()
调用是异步的。
此外,在您的构造函数中放置一个无限 while
循环将导致 UI 线程永远不会执行超出该点的代码,因此系统甚至不会完成单个布局传递,并且您的视图将永远不会被绘制一次。不用说,不要这样做。
【讨论】:
以上是关于Invalidate 未调用自定义视图类的 onDraw的主要内容,如果未能解决你的问题,请参考以下文章