Android glSurfaceView with overlay using XML/Java

2019-02-17 10:52发布

问题:

I started an Android OpenGL application and I have the following classes:

class A extends Activity
class B extends GlSurfaceView implements Renderer

When class A's onCreate is called, it creates an object of type class B and calls:

setContentView(Bobject)

So far it works and I spent a few days on it.

Now I wanted to add buttons to my application and found the SurfaceViewOverlay example. That uses some XML to create a view hierarchy. I wanted to create something very similar to I simply cut and paste the XML code:

    <android.opengl.GLSurfaceView android:id="@+id/glsurfaceview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    <LinearLayout android:id="@+id/hidecontainer"
            android:orientation="vertical"
            android:visibility="gone"
            android:background="@drawable/translucent_background"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            ...

Now keeping in mind my original class hierarchy, how would I initialize my views? What should I write in onCreate() of my class A?

I tried using:

Bobject = new B(this);
GLSurfaceView glSurfaceView =
        (GLSurfaceView) findViewById(R.id.glsurfaceview);
    glSurfaceView.setRenderer(Bobject);

And it does draw the buttons and the GL view on the screen, but the GL view is unable to take in any input from taps/clicks.

This is likely because Bobject's onTouchEvent() is not called as it is only being used as a:

Renderer

and not a:

glSurfaceView

object.

Instead of the above code, what I really want is to have Bobject replace glSurfaceView. But I don't know how to do that. When I do findViewById(), it seems like the glSurfaceView is already created for now. How can I ask it to use an object of type B for the GL view?

Sorry about any newbie mistakes. Completely new to Android.

EDIT: I also tried this:

I also tried the following: In my XML file, I changed the GLSurfaceView to:

<com.bla.bla.B
            android:id="@+id/glsurfaceview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

And in my A class constructor I am calling:

// This returns null
Bobject = (B) findViewById(R.id.glsurfaceview);

// And this suspends the application. :(
setContentView(R.layout.surface_view_overlay);

How should I use my custom class that extends glSurfaceView in my XML file/Activity?

回答1:

Okay, so the proper way of doing this is to have a constructor in the B class which takes in:

B(Context context, AttributeSet attrs)
{
  super(context, attrs);
}

And in the XML layout, use this:

<com.bla.bla.B
        android:id="@+id/glsurfaceview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

The thing that was missing in my code was the constructor signature.



回答2:

An alternate way to solve this, is to leave your views attached to Activity A. So instead of using setContentView(B object) you use setContentView(A object) and inside your "A XML" file, is the GLsurfaceView view:

<android.opengl.GLSurfaceView android:id="@+id/glsurfaceview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

You can then refer to your B object in the Activity A, because it was inflated when you setContentView to A, instead of B:

GLSurfaceView glSurfaceView = (GLSurfaceView) findViewById(R.id.glsurfaceview);


glSurfaceView.setRenderer();  //no longer have to pass the object

I'm honestly not sure how to get it to work exactly the way you want, but in your case I'm not sure it ultimately makes a difference. Then again, I'm still a novice too. I'd be interested to learn how to do this in an alternate fashion as I asked a similar question just today.