1

我试图拦截onDraw()Androidandroid.view.View类的方法,以了解视图何时完成绘制自身(并随后启动其他操作)。

但是,这使我遇到了一些 Java 问题(我对 Java 的经验有限)。

我的 ActivityonCreate()方法包含以下代码:

LayoutInflater inflater = (LayoutInflater)   getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
View view = inflater.inflate(R.layout.nessiean, null);
setContentView(view);
doSomeOperations();

我定义了一个子类,其主要目的是定义一个内部状态并提供一个wait()方法:

class MyView extends View{
    int state=0;

    public MyView(Context context){
        super(context);
    }

    public MyView(Context context, AttributeSet attrs){
        super(context,attrs);
    }

    public MyView(Context context, AttributeSet attrs, int defStyle){
        super(context,attrs,defStyle);
    }

    protected void onDraw (Canvas canvas){
        super.onDraw(canvas);
        state=1;
    }

    public void waitforDraw(){
        while(state==0){};
    }
}

问题是:

  1. 如上所述,我是否需要重新定义我的子类中的所有公共构造函数?Java默认不调用它们?

  2. 我无法在我的onCreate()方法中替换以下行:

View view = inflater.inflate(R.layout.nessiean, null);

MyView view = inflater.inflate(R.layout.nessiean, null);

错误是:cannot convert from View to MyView

有什么提示吗?

===========================完整代码如下==================== =========

package com.example;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;

public class SoundActivity extends Activity {

    private Thread mWorkerThread;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //START: ALTERNATIVE WAY FOR CREATING THE VIEW
        //*first variant:
        //setContentView(R.layout.nessiean);
        //*second variant:
        LayoutInflater inflater = (LayoutInflater)   getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        MyView view = (MyView) inflater.inflate(R.layout.nessiean, null);
        setContentView(view);
        //STOP: ALTERNATIVE WAY FOR CREATING THE VIEW
        System.loadLibrary("soundtest");
        mWorkerThread =  new Thread(new Runnable() {
            public void run() {
                execute();      
            }
        },"Worker Thread");
        try{
            mWorkerThread.start();
            mWorkerThread.join(); 
        }
        catch (Exception e) {
            System.exit(1); 
        }
    }   

    private native void execute();
}

class MyView extends View{
    int state=0;

    public MyView(Context context){
        super(context);
    }

    public MyView(Context context, AttributeSet attrs){
        super(context,attrs);
    }

    public MyView(Context context, AttributeSet attrs, int defStyle){
        super(context,attrs,defStyle);
    }

    @Override
    protected void onDraw (Canvas canvas){
        super.onDraw(canvas);
        state=1;
    }

    public void waitforDraw(){
        while(state==0){};
    }
}
4

3 回答 3

3

如上所述,我是否需要重新定义我的子类中的所有公共构造函数?

这取决于 - 你想拥有所有这些构造函数吗?只声明你的班级需要的那些。

Java默认不调用它们?

不。如果您不声明任何构造函数,编译器将尝试为您创建一个形式为:

public ClassName() {
    super();
}

对于任何声明的构造函数,如果您没有显式链接到另一个构造函数(在超类或此类中),它将隐式添加super()- 即对超类中无参数构造函数的调用。如果该构造函数不存在或不可访问,您将获得编译时失败。

我无法在我的 onCreate() 方法中替换以下行:

View view = inflater.inflate(R.layout.nessiean, null);

MyView view = inflater.inflate(R.layout.nessiean, null);

如果调用实际上inflate会返回 的实例,那么您只需添加一个演员表:MyView

MyView view = (MyView) inflater.inflate(R.layout.nessiean, null);

我对充气机的了解还不够,无法确定这是否会起作用。

于 2012-04-16T13:21:39.433 回答
1
  1. 是的,如果你想调用如图所示的超类构造函数。这是有必要的。
  2. 尝试将View返回的从 inflate 转换为MyView.
于 2012-04-16T13:22:40.947 回答
0

在您的 nessiean.xml 文件中<View>...</View>,您需要简单地将其更改为 < ,而不是声明MyView>...</MyView>。这样,当您调用 findViewById 时,您实际上是在返回一个 MyView 对象

此外,您的 onCreate 方法应该是:

setContentView(R.layout.nessiean);
MyView myView = (MyView) findViewById(R.id.<whatever tag you gave the view);
于 2012-04-16T20:54:16.910 回答