getSupportFragmentManager().findFragmentByTag() gibt immer null zurück

  • 8 Antworten
  • Letztes Antwortdatum
F

fr3sh_pr1nce

Neues Mitglied
0
Hallo,

ich nutze den ActionbarSherlock um Fragments in meiner Android App zu verwenden. Nun habe ich das große Problem dass ich nicht in der Lage bin aus der MainActivity aus eine Komponente in einem Fragment zu aktualisieren.
Hier der Status Quo:

MainActivity.java:

Code:
public class MainActivity extends SherlockFragmentActivity
{
 //Fragments
 Fragment1 frag1;
 
 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main); 
 
  if (savedInstanceState == null)
  {
   android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
 
   frag1 = new Fragment1();
   ft.add(R.id.container_main_top_and_main, frag1, "FNM_TAG");
   ft.commit();
 
   TestLoadWebview();
 }
 
 private void TestLoadWebview()
 {
  String HTMLContent = "<html><body>You scored <b>192</b> points.</body></html>";
 
  Fragment1 fnm = (Fragment1)getSupportFragmentManager().findFragmentByTag("FNM_TAG"); //findFragmentByID funktioniert auch nicht... 
 
  //FEHLER!! fnm ist immer null
  fnm.UpdateWebView(HTMLContent); 
 }
}

Activity_main.xml:

HTML:
<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"
    tools:ignore="MergeRootFrame" >
 
    <RelativeLayout 
        android:id="@+id/container_main_top_and_main"
        android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_above="@+id/container_main_bottom">
    </RelativeLayout>   
 
    <RelativeLayout 
        android:id="@+id/container_main_bottom"
        android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentBottom="true">  
    </RelativeLayout>   
</RelativeLayout>

Fragment1.java:

Code:
public class Fragment1 extends SherlockFragment 
{
 WebView webview;
 
 @Override
    public View onCreateView(LayoutInflater inflater,  ViewGroup container, Bundle savedInstanceState) 
 {
        View v = inflater.inflate(R.layout.fragment_main_no_mission, container, false);
        webview = (WebView)v.findViewById(R.id.my_webview);
 
        return v;
    }
 
 public void UpdateWebView(String webviewContent)
 {
  webview.loadData(webviewContent, "text/html", null);
 }
 
}

Fragment1.xml:

HTML:
<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" >
 <!-- Top menu -->
 <RelativeLayout
     android:id="@+id/layout_topmenu"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentTop="true"
     android:background="@color/clr_main_background"
     android:gravity="center|left" >
     ...
  ...
 
 </RelativeLayout>
 
    <RelativeLayout 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/clr_main_background"
     android:gravity="center"
     android:layout_below="@+id/layout_topmenu" >
         <WebView 
             android:id="@+id/my_webview"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_alignParentLeft="true"
             android:layout_alignParentTop="true"
             android:gravity="center" />        
 
 </RelativeLayout>
</RelativeLayout>

Ich verstehe nicht, warum ich keine Referenz auf Fragment1 erhalte.
Hätte vielleicht jemand einen Tipp für mich?
Vielen vielen Dank!
 
Kann ich dir auch nicht sagen, aber hast du nicht schon die Referenz in frag1?
Musst du dann nochmal eine Referenz holen?
 
Hi,

sehe es wie amfa. Diese Zeile
Code:
Fragment1 fnm = (Fragment1)getSupportFragmentManager().findFragmentByTag("FNM_TAG"); //findFragmentByID funktioniert auch nicht...
ist unnötig. Da doch deine Klassenvariable "Fragment1 frag1" schon dein Fragment enthält.
Also würde in TestLostWebView() dashier genügen:
Code:
String HTMLContent = "<html><body>You scored <b>192</b> points.</body></html>";


 frag1.UpdateWebView(HTMLContent);

Gruß

Der ursprüngliche Beitrag von 10:13 Uhr wurde um 10:14 Uhr ergänzt:

P.s.: wobei ich mir eh nicht sicher bin, ob auf diese weise eine Activity mit einem Fragment kommunizieren sollte...

Gruß
 
Ahh!!
Ihr habt natürlich Recht!

Diese Zeile brauche ich nicht:

Code:
Fragment1 fnm = (Fragment1)getSupportFragmentManager().findFragmentByTag("FNM_TAG"); //findFragmentByID funktioniert auch nicht...

Der Fehler (Nullpointerexception) taucht hier auf:

Code:
public void UpdateWebView(String webviewContent)
 {
  //webview == null
  webview.loadData(webviewContent, "text/html", null);
 }

Kann ich beim Aufruf von UpdateWebView irgendwie eine Referenz auf die Webview bekommen?

@StefMa
Kannst Du mir einen Tipp geben wie ich besser mit einem Fragment kommunizieren kann?

Vielen Dank
 
Hi,

hatte das leider nur mal gehört, aber nie selbst umgesetzt. Aber hier scheint was zu stehen: Communicating with Other Fragments | Android Developers

Ähm, bei deinem Beispiel kannst du die Methode einfach ins Fragment schreiben ^^
Code:
@Override
    public View onCreateView(LayoutInflater inflater,  ViewGroup container, Bundle savedInstanceState) 
 {
        View v = inflater.inflate(R.layout.fragment_main_no_mission, container, false);
        WebView webview = (WebView)v.findViewById(R.id.my_webview);
        String HTMLContent = "<html><body>You scored <b>192</b> points.</body></html>";
        webview.loadData(HTMLContent, "text/html", null);
        return v;
    }
Aber das geht halt eben nur bei diesem Beispiel. Ich weiß nicht genau was du vorhast um "flexibel" zu bleiben...

Gruß
 
An sich möchte ich "nur" bei Bedarf einen Text in der Webview (in einem Fragment) aktualisieren.
Sowas könnte man brauchen um beispielsweise regelmäßig den letzten RSS Beitrag abzurufen und darzustellen. Dann hätte ich in meinem Fragment immer die letzte Nachricht angezeigt.
In der onCreateView Methode bringt mir das dann leider nichts.
 
Wenn du die Doku zur FragmentTransaction liest siehst du wo das Problem ist:
"Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready. "

Du machst das commit() im main thread, (das noch nicht ausgeführt wird) direkt danach bist du aber noch immer im main thread und rufst TestLoadWebview() auf.
Diese Methode wird auch im main thread ausgeführt, direkt danach.

Das heißt das commit, kann noch nicht ausgeführt worden sein, da der main thread
an dieser Stelle:
webview.loadData(webviewContent, "text/html", null);

durchgehend beschäftigt war.
Somit ist das commit() nocht nicht endgültig ausgeführt (es steht also noch in der Warteschlange) worden und die OnCreateView Methode des Fragments wurde noch nicht aufgerufen, deshalb ist webview an der Stelle auch noch null.

Du kannst aber direkt nach dem commit() folgendes aufrufen:
FragmentManager | Android Developers

Dann werden die commits() alles sofort ausgeführt.
Sollte man allerdings nicht bei großen Fragments machen, ich denke das könnte den UI Thread sonst blockieren.
 
Perfekt - das ist es!
Kaum ruft man die Methode TestLoadWebview() woanders auf (z.B. auf Knopfdruck), klappt alles.

Herzlichen Dank an alle für die Hilfe!
 
Zurück
Oben Unten