SurfaceView in XML | Wie bekomme ich eine Referenz im Code der Activity?

  • 5 Antworten
  • Letztes Antwortdatum
R

Roccosi7

App-Anbieter (kostenlos)
0
Hi,
Ich habe folgendes Problem:
In einem kleinen Spiel, an welchem Ich grade arbeite, wird innerhalb des Layout-XML-Files ein SurfaceView erzeugt.
Code:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context=".FullscreenActivity"
    android:layout_above="@+id/relativeLayout3" >

    <com.example.tetrisandroid.GameView
        android:id="@+id/gameView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</FrameLayout>

Nun möchte ich im Programmcode der Activity eine Referenz auf diesen SurfaceView haben.
Mit z.B. einem Button würde man das ja folgendermaßen anstellen:
Code:
bExit = (Button) findViewById(R.id.bExitGame2);

Wenn ich jedoch versuche, meinen SurfaceView auf diese Weise im Code zu referenzieren;
Code:
		theGameView = (GameView) findViewById(R.id.gameView1);

bleibt theGameView null.

Warum ist das so und wie bekomme ich die gewollte Referenz?

Wenn ich gleich
Code:
setContentView(new GameView(this));
schreibe, funktioniert alles ohne Probleme, nur bin ich bei der Umsetzung auf ein Layout angewiesen...

mfg Rocco
 
wenn du "setContentView" aufrufst lädst du das xml file, in der deine View drin ist.
(also setContentView(findViewById(R.layout.relativeLayout3));)

Somit wird auch die dein GameView gleich mit geladen. Das kannst du ganz einfach mit dem LogCat nachvollziehen, indem du in die "onCreate"s der einzelnen klassen einfach ein Log.i(TAG, "onCreate"); hinzufügst. Da siehst du dann wunderbar die Reihenfolge.

Lange Rede, kurzer Sinn:

wenn du die View suchst bevor du den Content geladen hast, existiert sie nicht


Nachtrag:
Was du momentan machst ist, die View direkt zu setzten, also kein Layout.
Wenn du aber dein Layout lädst, wird auch die Referenz auf deine GameView geladen, welche du dann auch finden kannst.
 
Zuletzt bearbeitet:
Also wenn ich das jetzt richtig verstanden habe, sollte
Code:
setContentView(R.layout.activity_fullscreen);
theGameView = (GameView) findViewById(R.id.gameView1);
doch funktionieren? Warum ist der GameView trotzdem immernoch null?
Der ContentView wurde an dieser Stelle ja vor theGameView gesetzt.
Trotzdem kommt es zur NPE.

Kann auch sein das ich irgendetwas völlig falsch mache, aber wie mache ich es richtig?

mfg Rocco
 
Also ich finde jetzt nicht genau den Fehler, aber ich habe dir mal ein (bei mir funktionierendes) workaround gebastelt:

Schritt 1: Du ersetzt im Layout dein GameView durch ein FrameLayout und gibst ihm die Id game_view_placeholder

Schritt 2:

Du machst setContentView mit dem Layout

Schritt 3:
placeholder View mit deinem SurfaceView ersetzten.
Das geht so:

Code:
GameView v = new GameView(getApplicationContext());
View placeholder = this.findViewById(R.id.game_view_placeholder);
ViewGroup parent = (ViewGroup) placeholder.getParent();
int idx = parent.indexOfChild(placeholder);
parent.removeView(placeholder);
parent.addView(v, idx);

dann müsstest du dein SurfaceView dort haben wo du es hin haben willst.

eine andere Möglichkeit wäre noch, dass du dein GameView mit einem anderen Layout überlagerst. also erst:

Code:
setContentView( GameView(getApplicationContext());
View gui = View.inflate(getApplicationContext(), R.layout.gui, null);
addContentView(gui);
das habe ich z.b. bei meinem Spiel gemacht um Steuerelemente auf die jpct engin zu bekommen.
 
Die erste Möglichkeit funktioniert leider nicht, weil der placeholder, genau wie vorher der GameView, null bleibt.
Der 2. Vorschlag funktionierte jedoch Wunderbar!
In meinem Fall sieht das jetzt so aus:
Code:
theGameView = new GameView(this);

		setContentView(theGameView);
		View gui = View.inflate(getApplicationContext(), R.layout.activity_fullscreen_gui, null);
		LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		addContentView(gui, params);

Vielen Dank dafür! :)

mfg
 
das ist ja schon echt mysteriös bei dir :D
 
Zurück
Oben Unten