简体   繁体   中英

Java subclass constructor from superclass

I am trying to intercept the onDraw() method of the Android android.view.View class, to have a clue about when the view has finished to draw itself (and subsequently launch other operations).

However, this conducted me to some Java questions (I have limited experience with Java).

My Activity onCreate() method contains the following code:

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

I defined a subclass, whose main purpose is to define an internal state and provide a wait() method:

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

Questions are:

  1. do I need to re-define all the public constructors in my subclass, as above? Java does not call them by default?

  2. I cannot replace in my onCreate() method the line:

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

with

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

The error being: cannot convert from View to MyView .

Any hints?

==========================FULL CODE FOLLOWS==============================

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

do I need to re-define all the public constructors in my subclass, as above?

It depends - do you want to have all those constructors? Only declare the ones that your class needs.

Java does not call them by default?

No. If you don't declare any constructors, the compiler will attempt to create one for you of the form:

public ClassName() {
    super();
}

For any declared constructor, if you don't explicitly chain to another constructor (either in the superclass or this class) it will implicitly add super() - ie a call to the parameterless constructor in the superclass. If that constructor doesn't exist or is inaccessible, you'll get a compile-time failure.

I cannot replace in my onCreate() method the line:

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

with

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

If the call to inflate will actually return an instance of MyView , then you can just add a cast:

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

I don't know enough about the inflater to say for sure whether that will work.

  1. Yes, if you want to call the super class constructor as shown. It's necessary.
  2. Try casting the View returned from inflate to MyView .

In your nessiean.xml file, instead of declaring <View>...</View> , you need to simply chagne it to < MyView>...</MyView> . This way you are actually returning a MyView object when you call findViewById

Also, your onCreate method should just be:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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