【问题标题】:Java class member not being initialized in constructor?Java类成员没有在构造函数中初始化?
【发布时间】:2015-03-04 13:48:29
【问题描述】:

我正在尝试在 Android 中制作自定义视图。在调用 onDraw() 时,类成员 r 似乎没有被初始化。但是 paint 仍然成功初始化(如果我从构造函数中删除该行,则应用程序强制关闭)。在最后一行,我有画布绘制r1,它成功并绘制了一个蓝色矩形。如果我将r1 替换为r,它就是白色的。

这是我的问题的简化版本。我一直在为在构造函数中初始化的数组成员获取空指针异常。但无论如何,问题似乎都是一样的。为什么它不保持实例化?

public class ColorListView extends View {
Paint paint;
Rect r;

public ColorListView (Context context, AttributeSet attrs){
    super(context, attrs);
    paint = new Paint();
    r = new Rect(0,0,getWidth(),getHeight());
}


protected void onDraw (Canvas canvas){
    paint.setColor(Color.BLUE);
    Rect r1 = new Rect(0,0,getWidth(),getHeight());
    canvas.drawRect(r1, paint); // doesn't work if r is passed to drawRect?
}}

【问题讨论】:

  • 您是否 100% 确定这是运行的构造函数,而不是任何其他构造函数? View 有大约 3 个不同的构造函数。
  • 您是否在代码中的某处重置 r?
  • 如果onDrawsuper(...)调用,那么确实r还没有被初始化,所以onDraw将无法使用它。
  • @EpicPandaForce 这是我正在使用的唯一构造函数,所以...是吗?
  • @SMA 不,您看到的是我遇到此问题时使用的所有代码。

标签: java android


【解决方案1】:

在最后一行,我有画布绘制 r1,它成功和一个蓝色 矩形被绘制。如果我用 r 替换 r1,它就是白色的。

r = new Rect(0,0,getWidth(),getHeight());

您可以在构造函数上执行此操作,因为此时 getWidth()getHeight() 返回 0。您必须等到实际测量视图。在documenation 上,您可以找到有关onMeasure 回调的更多信息

【讨论】:

  • 谢谢。我将该行移至 onMeasure() 的覆盖处,它起作用了。
  • 后续问题——现在我在构造函数中初始化 Rect 被认为是最佳实践(实际上是我想要的矩形数组)。现在我在onDraw() 中设置了r.bottomr.right,它工作正常,但我想知道我是否应该在onLayout() 中这样做?还是没关系?
  • 是的,你是对的。您可以只调用 setter,但必须等到测量视图,否则这些方法返回 0。在这种情况下,在 onDraw、onMeasure 或 onLayout 中调用 setter 并没有太大区别。
【解决方案2】:

如何做这样的事情: 在你调用构造函数的地方

ColorListView myView = new ColorListView(context, attrs);
myView.createRectangle();
myView.invalidate();

在课堂上

public class ColorListView extends View {
    Paint paint;
    Rect r;

    public ColorListView (Context context, AttributeSet attrs){
        super(context, attrs);
        paint = new Paint();
    }


    protected void onDraw (Canvas canvas){
        paint.setColor(Color.BLUE);
        canvas.drawRect(r, paint);
    }

    public void CreateRectangle() {
        Rect r = new Rect(0,0,getWidth(),getHeight());
    }
}

或者查找实际创建视图的时间。以上是我一秒钟前刚编的一个快速方法。我不记得视图是什么时候创建/测量的。

PS - 我刚刚看到 onMeasure() 的答案,我没有思考是不好的:P

【讨论】:

  • 在我意识到 Rect WAS 被初始化后,只是不正确,我将其移回构造函数并在 onDraw 中分配了 r.bottomr.right
【解决方案3】:

Rect r 在 View 被测量之前被初始化,所以 getWidth 和 getHeight 为 0。

尝试在视图的 onMeasure 之后对其进行初始化。

另外,这样做是一种不好的做法

Rect r1 = new Rect(0,0,getWidth(),getHeight());

在你的

onDraw (Canvas canvas)

你应该避免在那里分配对象。

【讨论】:

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