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的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个类调用 invalidate() 方法?

刷新片段内的视图

未调用 CScrollView OnDraw

Android自定义圆角矩形进度条2

自定义视图中未调用 UIButton 操作

Swift:在自定义视图中未调用 UIButton 触摸事件