繁体   English   中英

来自超类的Java子类构造函数

[英]Java subclass constructor from superclass

我试图拦截Android android.view.View类的onDraw()方法,以获得关于视图何时完成绘制自身(并随后启动其他操作)的线索。

然而,这引发了我一些Java问题(我对Java的经验有限)。

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

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){};
    }
}

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

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

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);

我对inflater的了解不足以确定这是否有效。

  1. 是的,如果你想调用超类构造函数,如图所示。 这是有必要的。
  2. 尝试将从MyView返回的View转换为MyView

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

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

setContentView(R.layout.nessiean);
MyView myView = (MyView) findViewById(R.id.<whatever tag you gave the view);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM