Methode von Fragment durch Activity rufen scheitert

CT9288

Mitglied
Hallo Ihr lieben. Ich habe mal wieder ein Problem, nachdem ich schon seit 2 Stunden im Internet am suchen bin und einfach keine Lösung finde. Kurzer Umriss: es handelt sich um eine BattleActivity.java die in ihrer .xml datei ein Framelayout enthält, indem eine von zwei Fragments angezeigt werden soll. Das Anzeigen läuft und scheinbar auch der Wechsel zwischen beiden. Nun, wenn die BattleActivity startet, soll zuerst BattleTextFragment geladen werden, zusammen mit einem von 3 Strings, der zufällig generiert wird. Wenn ich diese Funktion innerhalb des Fragments ablaufen lasse, funktioniert das auch prima, aber nun möchte ich (es ist ein Kampf Szenario) die zwei Fragments über die BattleActivity laufen lassen, dafür müsste ich nun die TextView innerhalb des BattleTextFragments durch BattleActivity verändern, indem ich eine Methode gerufen hätte, die man innerhalb des Fragments findet. Aber das scheitert und ich weiß nicht weiter.

[CODE lang="java" title="BattleActivity.java"]package com.manticore.monochromia;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.content.Intent;
import android.os.Bundle;

public class BattleActivity extends AppCompatActivity {

private Randomizer rnd = new Randomizer();

private Fragment frag1 = new BattleTextFragment();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_battle);


SetFragment(frag1);
Battle();
}


@Override
public void onBackPressed(){
super.onBackPressed();
this.finish();
Intent i = new Intent(this, DebugMenuActivity.class);
startActivity(i);
overridePendingTransition(0,0);
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
}

private void SetFragment(Fragment fragment){

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmentContainer, fragment);
fragmentTransaction.commit();

}

public void Battle(){
BattleStart();
}

public void BattleStart(){
BattleTextFragment frag1 = (BattleTextFragment) getFragmentManager().findFragmentById(R.id.fragBtlTxt);
// bei dem oberen zeigt mir die Doku immer "Inconvertible types; cannot cast 'android.app.Fragment' to 'com.manticore.monochromia.BattleTextFragment'"
int ranNum = rnd.Randymizer(0, 3);
frag1.UpdateBattleText(ranNum);
}

}[/CODE]

[CODE lang="xml" title="activity_battle.xml"]<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:weightSum="2"
android:eek:rientation="horizontal"
android:background="@color/colorPrimary"
tools:context=".BattleActivity">

<RelativeLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent">

<ImageView
android:id="@+id/delete"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:scaleType="fitXY"
app:srcCompat="@drawable/mob_shellshock" />

</RelativeLayout>

<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:eek:rientation="vertical"
android:weightSum="6">

<RelativeLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:layout_centerInParent="true"
android:layout_toStartOf="@id/slash"
android:layout_marginRight="10dp"
android:text="53"/>

<TextView
android:id="@+id/slash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:layout_centerInParent="true"
android:text="/"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:layout_centerInParent="true"
android:layout_toEndOf="@id/slash"
android:layout_marginLeft="10dp"
android:text="100"/>

</RelativeLayout>

<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_weight="5"
android:layout_width="match_parent"
android:layout_height="0dp" />

</LinearLayout>

</LinearLayout>[/CODE]

[CODE lang="java" title="BattleTextFragment.java"]package com.manticore.monochromia;

import android.content.Intent;
import android.os.Bundle;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class BattleTextFragment extends Fragment implements View.OnClickListener {

private Randomizer rnd = new Randomizer();
private BattleText btlTxt = new BattleText();

ImageView changeFragment;
public TextView battleText;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_battle_text, container, false);

battleText = (TextView) view.findViewById(R.id.battleText);

changeFragment = (ImageView) view.findViewById(R.id.changeFragment);
changeFragment.setOnClickListener(this);

return view;
}

@Override
public void onClick(View v){
//implement your things
Fragment battleActionFragment = new BattleActionFragment();
FragmentTransaction transaction= getFragmentManager().beginTransaction();
transaction.replace(R.id.fragmentContainer, battleActionFragment);
transaction.addToBackStack(null);
transaction.commit();
}


public void UpdateBattleText(int i){
battleText.setText(btlTxt.btlIntrTxt);
}
}[/CODE]

[CODE lang="xml" title="fragment_battle_text.xml"]<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fragBtlTxt"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".BattleTextFragment">

<TextView
android:id="@+id/battleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="10dp"
android:textAlignment="center"
android:textSize="25sp"
android:text="@string/battleTextFragment" />

<ImageView
android:id="@+id/changeFragment"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="10dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
app:srcCompat="@drawable/game_orb"/>

</RelativeLayout>[/CODE]

ich weiß nicht weiter, ich hatte so nen guten Lauf, und jetzt hänge ich mal wieder an einer so blöden Stelle. Ich wette, dass nur irgendwo wieder ein blödes Semicolon fehlt...
ich danke euch schon jetzt für euren Beistand
 

CT9288

Mitglied
Okay. Es hat sich etwas geändert.

[CODE lang="java" title="BattleActivity.java"][...]

public void BattleStart(){
BattleTextFragment frag1 = (BattleTextFragment) getSupportFragmentManager().findFragmentById(R.id.fragBtlTxt);
int ranNum = rnd.Randymizer(0, 3);
frag1.UpdateBattleText(ranNum);
}[/CODE]

habe statt getFragmentManager nun getSupportFragmentManager geschrieben. Der Fehler hat sich nun in einen nullpointer Fehler geändert.

[CODE title="Debug"]E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.manticore.monochromia, PID: 16482
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.manticore.monochromia/com.manticore.monochromia.BattleActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.manticore.monochromia.BattleTextFragment.UpdateBattleText(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3139)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3282)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1970)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.manticore.monochromia.BattleTextFragment.UpdateBattleText(int)' on a null object reference
at com.manticore.monochromia.BattleActivity.BattleStart(BattleActivity.java:65)
at com.manticore.monochromia.BattleActivity.Battle(BattleActivity.java:59)
at com.manticore.monochromia.BattleActivity.onCreate(BattleActivity.java:35)
at android.app.Activity.performCreate(Activity.java:7340)
at android.app.Activity.performCreate(Activity.java:7331)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3119)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3282)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1970)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
[/CODE]
 

Jw456

Top Contributor
Okay. Es hat sich etwas geändert.

[CODE lang="java" title="BattleActivity.java"][...]

public void BattleStart(){
BattleTextFragment frag1 = (BattleTextFragment) getSupportFragmentManager().findFragmentById(R.id.fragBtlTxt);
int ranNum = rnd.Randymizer(0, 3);
frag1.UpdateBattleText(ranNum);
}[/CODE]
Erstmal solltest du prüfen ob überhaupt das richtige Fragment geladen wurde (angezeigt wird)

Java:
public void BattleStart() {

        if (findViewById(R.id.fragBtlTxt) != null) {
            BattleTextFragment frag1 = (BattleTextFragment) getSupportFragmentManager().findFragmentById(R.id.fragBtlTxt);
            frag1.UpdateBattleText(ranNum);
        }
    }
 

Jw456

Top Contributor
Frage zum ersten Start deines Fragment.
was ist die Variable "fragment"
Java:
fragmentTransaction.replace(R.id.fragmentContainer, fragment);
wo und wie wird die erstellt?

Zweitens macht man das setzen des ersten Fragment nicht mit replace sondern mit add.
Du hast ja noch kein Fragment geladen was du tauschen willst.
 

Jw456

Top Contributor
welche compileSdkVersion und targetSdkVersion benutzt du ?
denn getSupportFragmentManager ist seit API 28 veraltet.
Ich denke du benutzt auch androidx .
 

CT9288

Mitglied
Vielen Dank für deine Antwort, ich versuche mal, deine Gegenfragen zu beantworten:
1. Ja, augenscheinlich benutze ich androidx, zumindest werden die meisten Importe mit androidx initiiert. Was genau hat es damit auf sich? Zur Info, alles was ich lerne und weiß, weiß ich aus Tutorials auf Youtube und ein paar anderen Seiten, dass viele der Tutorials veraltet sind, leuchtet mir ein, aber andere Quellen habe ich teilweise nicht, die es mir so verständlich erklären, wie die Video-Tutorials.
2. compileSdkVersion = 29
3. targetSdkVersion =29
4. Wenn es nicht getFragmentManager ist und auch nicht getSupportFragmentManager, dann, keine Ahnung
5. Fragment in diesem Zusammenhang ist ja nur eine Methodeninterne Variabel.
Ich habe ein neues Objekt meines Fragments erstellt:
[…]
private Fragment frag1 = new BattleTextFragment();
[…]
Dann in meiner onCreate
SetFragment(frag1);

Und das ist die ganze Methode SetFragment:
private void SetFragment(Fragment fragment){

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmentContainer, fragment);
fragmentTransaction.commit();

}

Du siehst, bei fragment handelt es sich um mein frag1, und ja, womöglich ist replace falsch, aber laden kann ich das Fragment damit. Es gibt nur ein Problem, wenn ich über die Activity eine TextView im Fragment verändern möchte.
Wenn ich das nicht zum laufen bekomme, dann muss ich mir ne Alternative suchen.
Mein Hintergrundgedanke ist, wie bei Pokemon oder so, du hast die Auswahl aus Angriff, Items, etc. wenn du dann eines gewählt hast, verschwindet die Auswahl und macht Platz für ein Textfeld, in dem der Kampfablauf dargestellt wird. So ähnlich hätte ich es hier gerne.
 

Jw456

Top Contributor
Du importirst
import androidx.fragment.app.FragmentManager;
Also solltest du auch den benutzen und nicht den aus den Support libs.

Und das im gesamten Projekt gleich. Kein Mischen zwischen Support und nicht Support.

Wenn du denn menager im Fragment brauchst dann benutze den Context der Activity dazu.
 

Jw456

Top Contributor
versuche es mit dem getSupportFragmentManager()
AppCompatActivity erbt von

Wird denn dein erstes Fragment überhaupt in den Frame Layout angezeigt auf dem Bildschirm?


Was ich auch nicht gut finde ist das du eine Instanzvariable „frag1“ hast.
Und in der Methode BattleStart() eine lokale Variable mit dem gleichen Bezeichner erstellt. Das führt oft zu Verwechslungen.
Auch sollten Methoden Namen mit kleinen Buchstaben beginnen. Am besten mit einem kleinen Verb.

Mit
Java:
fragment =  getSupportFragmentManager().findFragmentById(R.id.fragment_container);
bekommst du die Instanz des letzten hinzugefügten Fragments .

deshalb vorher prüfen ob die id des layouts auch gefunden wird. Und auch das Fragment aus dem du eine Methode aufgufen willst geladen ist.

Java:
public void BattleStart() {

        if (findViewById(R.id.fragBtlTxt) != null) {
            BattleTextFragment frag1 = (BattleTextFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
            frag1.UpdateBattleText(ranNum);
        }
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Regelmäßig eine Methode im Hintergund ausführen Android & Cross-Platform Mobile Apps 1
K Methode wird nicht gefunden Android & Cross-Platform Mobile Apps 1
L Android Methode funktioniert nicht unter Android Android & Cross-Platform Mobile Apps 3
R Android App mit Datenbankeinträgen und Math.random() Methode programmieren Android & Cross-Platform Mobile Apps 0
J Android button mithilfe einer Methode automatisch erstellen Android & Cross-Platform Mobile Apps 6
Z Canvas onDraw() Variablen muss in der Methode initialisiert werden Android & Cross-Platform Mobile Apps 1
S Auf Methode zugreifen von anderen Klassen Android & Cross-Platform Mobile Apps 6
G Back-Button Methode überschreiben Android & Cross-Platform Mobile Apps 2
G eine Methode einer anderen Activity aufrufen Android & Cross-Platform Mobile Apps 9
P Android Sort Methode von ArrayAdapter überschreiben Android & Cross-Platform Mobile Apps 5
K Apps durchsuchen nach verwendeter Methode Android & Cross-Platform Mobile Apps 4
F Android Fehlermeldung bei onClick-Methode Android & Cross-Platform Mobile Apps 2
R Meine arctan-Methode geht nicht Android & Cross-Platform Mobile Apps 6
U Probleme mit der drawString Methode bei Canvas Android & Cross-Platform Mobile Apps 8
W Relativelayout in Fragment Android & Cross-Platform Mobile Apps 46
W onViewCreated blockiert Session Zugriff gegensatz zu onCreateView? Fragment Android & Cross-Platform Mobile Apps 25
W Bild aus dem Internet in View bzw. ImageView laden (Fragment) Android & Cross-Platform Mobile Apps 2
Noahscript Android Verhindern, dass Fragment Transaktion die UI blockt Android & Cross-Platform Mobile Apps 7
L Android Leiste unter Fragment Android & Cross-Platform Mobile Apps 2
J Dialog in Fragment Android & Cross-Platform Mobile Apps 6
P Herausfinden, welches Fragment gerade angezeigt wird. Android & Cross-Platform Mobile Apps 1
N Android Retain-Fragment + ActionBar-Tabs = Absturz!? Android & Cross-Platform Mobile Apps 9
D Android Fragment/FragmentActivity in Popupwindow Android & Cross-Platform Mobile Apps 4
H Android Nullpointer Exception bei Methodenaufruf durch MainActivity Android & Cross-Platform Mobile Apps 3
B Android Kontrolle ob in Reichweite durch zeitlich versetzte If Abfrage oder Delay? Android & Cross-Platform Mobile Apps 1
F Mit Canvas zeichen und durch einen Timer aktualiesieren Android & Cross-Platform Mobile Apps 1
H Android 3G TCP Socket Verbindung zum PC durch NAT Android & Cross-Platform Mobile Apps 8
K Grafik Tablerow, Button erstreckt sich in der gesamten Breite trotz Beschrenkung durch (max)width Android & Cross-Platform Mobile Apps 2
D Android Java-Umfang durch Apps-Entwicklung? Android & Cross-Platform Mobile Apps 1

Ähnliche Java Themen

Neue Themen


Oben