Button in SurfaceView integrieren

Diskutiere Button in SurfaceView integrieren im Mobile Geräte Bereich.
A

AkechiKogoro

Hallo an alle im Java-Forum,

ich habe folgendes Problem:
Ich habe eine Klasse "GameView" geschrieben, die die Klasse SurfaceView erweitert. Bei der Erzeugung eines GameView-Objektes mit "private GameView gameView = new GameView(this);" wird ja mit "this" der gesamte Context der App und damit die ganze Oberfläche in die GameView einbezogen ( so viel ich weiß ).
Im Konstruktor dieser Klasse wird mit "SurfaceHolder myHolder = getHolder();" auf Basis der GameView ( erweiterte SurfaceView) ein SurfaceHolder erzeugt, mit dem ich die Spielfigur laufen lassen kann. So weit funktioniert das auch. Jedoch läuft die Figur nur los wenn man irgendwo auf den Bildschirm tippt.
Jetzt möchte ich aber ein ein Button ( als Anfang für ein Steuerkreuz ) einbeziehen und will damit erreichen dass die Spielfigur nur losläuft, wenn man diesen Button betätigt.
Was noch zu erwähnen ist: In der onCreate()-Methode steht bei mir "setContentView(gameView)"

Wie kann ich über die SurfaceView einen Button legen? Oder gibt es eine andere Möglichkeit dies zu realisieren?

Ich hoffe dass mir diesbezüglich jemand weiterhelfen kann.

Viele Grüße
euer Akechi Kogoro
 
mihe7

mihe7

Aus der Doku
https://developer.android.com/reference/android/view/SurfaceView hat gesagt.:
The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.
Sprich: ein Layout erstellen, das neben der SurfaceView ein weiteres Layout mit den Buttons enthält. Beispiel hierzu unter https://stackoverflow.com/a/5779267
 
A

AkechiKogoro

Ich habe es nach dem Schema versucht wie du es vorgeschlagen hast @mihe7, jedoch leider ohne Erfolg. Hier ein Auszug aus dem was ich gemacht habe:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<ImageButton
android:id="@+id/iBtnNachRechts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@android:drawable/ic_media_play" />

<com.example.runningman2.MainActivity.GameView
android:id="@+id/gameView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/iBtnNachRechts"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>


Und im Activity selbst:

...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); -> Zeile 24
gameView = findViewById(R.id.gameView);
}

...

Daraufhin ist folgender Fehler aufgetreten:

E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.runningman2/com.example.runningman2.MainActivity}: android.view.InflateException: Binary XML file line #20: Error inflating class com.example.runningman2.MainActivity.GameView
...
at com.example.runningman2.MainActivity.onCreate(MainActivity.java:24)

( Ich habe keine Ahnung warum er die "activity_main", in der sich jetzt die GameView "gameView" befundet nicht mehr findet )
 
A

AkechiKogoro

"activity_main" ist das Layout und "gameView" ist ein GameView-Objekt ( eine Ableitung aus der Klasse SurfaceView ). Ich habe versucht die GameView "gameView" innerhalb ( mit XML ) des Layouts "activity_main" und dort im ConstraintLayout zu integrieren. Das hat leider aber nicht funktioniert.

Mir ist in der DesignAnsicht noch folgende Warnmeldung aufgefallen:
The following classes could not be found:
- com.example.runningman2.MainActivity.GameView (Fix Build Path, Edit XML, Create Class)


( In der XML-Ansicht wird nichts beanstandet, weswegen ich die Warnmeldung erst später entdeckt hatte )
Wenn es daran liegen sollte: Wie kann ich das korrigieren? ( Die Klasse existiert ja immerhin in der Activity ).
 
Zuletzt bearbeitet:
mihe7

mihe7

Das hier com.example.runningman2.MainActivity.GameView sieht aus, als hättest Du die Klasse GameView innerhalb der Klasse MainActivity definiert. Das funktioniert so nicht. Du musst die Klasse GameView in einer eigenen Datei definieren und den vollqualifizierten Namen der Klasse angeben. Alternative dazu findest Du in dem Link oben.
 
A

AkechiKogoro

Danke für den Tipp. Die Klasse wird jetzt erkannt.
Jedoch hat die App schon wieder 2 neue Probleme aus denen ich nicht schlau werde:
Render Problem
Custom view GameView is not using the 2- or 3-argument View constructors; XML attributes will not work
Tip: Try to refresh the layout.

Render Problem
Color spaces are not supported
Tip: Try to refresh the layout


Der refresh hat aber leider nichts geändert.
 
mihe7

mihe7

Das steht alles in dem Link, z. B. "There is a form of the constructor that are called when the view is created from code and a form that is called when the view is inflated from a layout file. The second form should parse and apply any attributes defined in the layout file."

Gib Deiner Klasse alle Konstruktoren, die auch SurfaceView hat und rufe super(...) auf.
 
A

AkechiKogoro

Mein bisher schon verwendeter Konstruktor sieht folgendermaßen aus:
public GameView(Context context ) {
super(context);
ourHolder = getHolder();
bitmapRunningMan = BitmapFactory.decodeResource(getResources(), R.drawable.running_man);
bitmapRunningMan = Bitmap.createScaledBitmap(bitmapRunningMan, frameWidth * frameCount, frameHight, false);
}


Die anderen Konstrunktoren benötigen ebenfalls alle einen Context:
SurfaceView(Context context)
SurfaceView(Context context, AttributeSet attrs)
SurfaceView(Context context, AttributeSet attrs, int defStyleAttr)
SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

Wie kann ich nun ( ggf. damit ) realisieren dass sich die GameView nicht die ganze Oberfläche schnappt, damit ich darunter noch den Button packen kann?

Auch meckert der Compiler noch an folgender Zeile rum:
setContentView(R.layout.activity_main);
Das macht er aber erst seit ich die GameView wie folgt in die XML-Datei "activity_main" geschrieben habe ( Deswegen denke ich ist der Konstruktor nicht das Problem, denn der wird erst in der Zeile danach aufgerufen ).

<com.example.runningman2.GameView
android:id="@+id/gameView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/iBtnNachRechts"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />


Die gleichen Warnungen aus in meinem Beitrag von heute 15:58 Uhr sind leider noch immer darin sichtbar.
 
mihe7

mihe7

A

AkechiKogoro

Danke @mihe7,
dank deiner Hilfe hat es jetzt endlich geklappt. Ich hätte nicht gedacht dass es daran liegt dass ich nicht alle Konstruktoren aus SurfaceView umgesetzt hatte. Da habe ich wieder etwas gelernt.

Vielen Dank nochmal! :)
 
Thema: 

Button in SurfaceView integrieren

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben