簡體   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