我在android的Textview类中看到了这个:
@Override
protected void onDraw(Canvas canvas) {
restartMarqueeIfNeeded();
// Draw the background for this view
super.onDraw(canvas);
在View
类的android中,我看到它是空的:
/**
* Implement this to do your drawing.
*
* @param canvas the canvas on which the background will be drawn
*/
protected void onDraw(Canvas canvas) {
}
为什么有人会调用超级类的方法呢?
使用参数画布调用的方法在哪里?
android系统是否自动传递参数画布?
何时调用提取方法并由谁调用?
当它被覆盖时,是否调用了子类的方法而不是超类'?
这是我的自定义视图,例如:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}
class MyView extends View {
public MyView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
谁调用MyView.OnDraw方法?
必须有一行代码调用Myview.Ondraw方法。不是吗?
答案 0 :(得分:2)
回答你的问题:
为什么有人会调用超级类的方法呢?
因为如果你不确定实现是什么的话,最好调用super。例如,如果您在库中有一个类的扩展类,并且您没有该代码,则应调用super方法。但是,在这种情况下,没有必要,但我会推荐它
使用参数画布调用的方法在哪里?
我不完全确定你的意思,但当你让你的课程覆盖View
时,你可以覆盖onDraw
,这样你就可以决定你的观点如何看待
android系统是否自动传递参数画布?
是
何时调用提取方法并由谁调用?
当它第一次变为可见时,它被附加到其生命周期中的某个地方。你不必担心。当您在视图上调用invalidate
或将其视为脏(需要重新绘制)时,也会调用它。在您的示例中,将调用onDraw
,但由于您未在提供的画布上绘制任何内容,因此您不会在Activity上看到任何内容。如果你在函数中添加一些日志,你会在logcat
当它被覆盖时,是否调用了子类的方法而不是超类'?
是的,这就是扩展类和重写方法的方法
答案 1 :(得分:1)
当有人通过调用onDraw
或invalidate
请求重新绘制其子视图时,ViewRoot会调用postInvalidateOnAnimation
。 ViewRoot正在调用每个Window子节点的onDraw
,然后它们将绘制其可见子节点(在ViewGroup的情况下)或它们自己(在视图的情况下)直到绘制最后一个视图。
绘图可以在主线程上随时执行,这是好的,并且在旧版本上是默认的,但在视觉上并不完美。或者,它可以通过Choreographer推迟到下一个垂直同步。现代Android版本通过Choreographer安排所有对onDraw
的调用,这是由失效和Drawable动画引起的。
Canvas由SurfaceFlinger - Android Window系统提供,内部使用OpenGL ES和硬件组合来管理显示的窗口。
当它被覆盖时,是否调用了子类的方法而不是超类'?
是。但是不调用超类的onDraw
很少是一种有效的策略(为什么你首先将它子类化?!)如果你不想要绘制任何东西,你可以调用setWillNotDraw(true)
(默认为顺便说一下,基本View类已经true
。
答案 2 :(得分:0)
除上述内容之外:在调整窗口大小以合理调整“键盘”后,软键盘会导致 View.invalidate() - > View.onDraw()序列。自定义 View.onDraw()必须使自己处于预期此可能性的状态 这可以解释为什么在带有蓝牙键盘的平板电脑上开发和测试的应用程序在现实世界中出乎意料地表现出来。