2013-03-16 4 views
5

Ich bin Anfänger in Android-Programmierung, so brauche ich Ihre aufrichtige Hilfe dafür. Jeder möge mir bitte helfen.Fragment-Fragment Kommunikation in Android

Ich versuche, ein gleitender UI Fragmente

so meine eigentliche Zweifel zu bauen ... Ich habe eine Fragment (sagen wir Fragment A) eine TextView und Button in sich hat und eine andere Fragment (sagen wir Fragment B). Es hat eine TextView drin. Ich muss die Fragment A 's TextView' s Inhalt in Fragment B's TextView zeigen, als ich die Button in FRAGMENT A. drückte ich versuchte viele Möglichkeiten, leider hatte ich nicht die richtige Ausgabe. Ich bin sicher, ihr Völker kennt es. Bitte hilf mir.

Danke

+0

Sie sollten den Text in der übergeordneten Aktivität speichern und beim Laden an FRAGMENT B übergeben. – dmaxi

+0

@dmaxi Aber ich weiß nicht, wie man Text in der Eltern speichert Aktivität – sam

+0

Erstellen Sie eine String-Typ-Member-Variable und vergessen Sie nicht, es in OnSaveInstanceState() Callback in Bundle zu speichern. Sie sollten auch den JavaDoc von Aktivität und Fragment lesen. – dmaxi

Antwort

14

Es sollte gedacht Zuhörer erfolgen, so Fragmente sind noch nicht voneinander abhängen und kann in einem oder zwei Teilfenster-Modus verwendet werden. Aktivität sollte Listener beider Fragmente behandeln. Hier

ist ein Beispiel für Aktivität mit zwei Fragmenten:

package com.example; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 

import com.example.fragment.FragmentA; 
import com.example.fragment.FragmentA.TextChangeListener; 
import com.example.fragment.FragmentB; 

public class ActivityAB extends FragmentActivity { 

    FragmentA fragmentA; 
    FragmentB fragmentB; 

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

     FragmentManager manager = getSupportFragmentManager(); 
     fragmentA = (FragmentA) manager.findFragmentById(R.id.fragmentA); 
     fragmentB = (FragmentB) manager.findFragmentById(R.id.fragmentB); 

     fragmentA.setTextChangeListener(new TextChangeListener() { 

      @Override 
      public void onTextChange(CharSequence newText) { 
       fragmentB.updateTextValue(newText); 
      } 
     }); 
    } 

} 

Hier ist Fragment A, die benutzerdefinierten Hörer für Text Änderungsereignis hat.

package com.example.fragment; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.TextView; 

import com.example.R; 

public class FragmentA extends Fragment { 

    TextChangeListener listener; 

    public interface TextChangeListener { 
     public void onTextChange(CharSequence newText); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_a, container, false); 

     Button btn = (Button) view.findViewById(R.id.button1); 
     final TextView textView = (TextView) view.findViewById(R.id.textView1); 

     btn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       if (null != listener) { 
        listener.onTextChange(textView.getText()); 
       } 

      } 
     }); 
     return view; 
    } 

    public void setTextChangeListener(TextChangeListener listener) { 
     this.listener = listener; 
    } 
} 

Hier ist Fragment B, die öffentliche Methode hat Textfeld zu aktualisieren:

package com.example.fragment; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import com.example.R; 

public class FragmentB extends Fragment { 

    TextView textView; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_b, container, false); 
     textView = (TextView) view.findViewById(R.id.textView1); 
     return view; 
    } 

    public void updateTextValue(CharSequence newText) { 
     textView.setText(newText); 
    } 
} 

ActivityAB xml Layout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:baselineAligned="false" 
    android:orientation="horizontal" > 

    <fragment 
     android:id="@+id/fragmentA" 
     android:name="com.example.fragment.FragmentA" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

    <fragment 
     android:id="@+id/fragmentB" 
     android:name="com.example.fragment.FragmentB" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

</LinearLayout> 

Fragment A xml Layout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="This is text" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

    <Button 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Show" /> 

</LinearLayout> 

Fragment B xml-Layout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="(here will be text)" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

</LinearLayout> 
+0

Hallo, danke für Ihre Antwort..aber das funktioniert nicht für mich..Und eine weitere Sache, ich habe nicht zwei separate Fragment layout in activity ab (ich habe natürlich zwei fragment class und entsprechende layout xml file) ... stattdessen habe ich nur ein fragment layout und ich ändere dynamisch den inhalt..kann bitte noch einmal versuchen für mich .. – sam

+0

Die Methode 'onTextChange' wird beim Button-Klick aufgerufen. Verwenden Sie diesen Rückruf, um Fragment A durch Fragment B zu ersetzen, und legen Sie den Text fest, den Sie erhalten, z. 'fragmentB.updateTextValue (neuerText); this.showFragmentB(); ' – andrew

+0

Dieser Hinweis gilt nicht im allgemeinen Fall. Was ist, wenn Sie Subfragmente verwenden? Ein Elternfragment und ein Kindfragment müssen möglicherweise miteinander kommunizieren, ohne dafür den ganzen Weg bis zur enthaltenen Aktivität gehen zu müssen. In bestimmten Fällen kann die Root-Aktivität die gesamte Anwendung enthalten (dh eine tab-basierte Anwendung). Es gibt keine Möglichkeit, jede einzelne Kommunikation zwischen jeder einzelnen Komponente an einer Stelle zu führen (Hauptverstoß des Single Responsibility Anti-Patterns). – Marchy

0

Kommunikation zwischen zwei Fragmente sollte immer über ihre Fragment Aktivität, um eine lose Kopplung zwischen den Fragmenten zu halten, also wenn Sie einige Daten von einem Fragment A zu einem anderen Fragment B senden Sie Hörer erstellen und implementieren Sie es in Ihrer Fragment-Aktivität und von innerhalb fragmentA können Sie das Ereignis mit diesem Listener auslösen und Daten an Fragment-Aktivität senden, So jetzt die Fragment-Aktivität wird das Objekt von Fragment B auch und so Fragment-Aktivität kann direkt die Methode des Fragments B und senden Daten an das Fragment B ...

2

Es klingt, als ob das Setup so etwas wie sein könnte - MainActivity w/fragmenta [hinzugefügt] und FragmentB [aufgenommen]. In diesem Fall würde ich Nachrichten/Aktionen zwischen den beiden Fragmenten über die MainActivity delegieren. Indem man MainActivity erlaubt, die Nachrichten/Aktionen zu handhaben, werden auch "spezielle" Orchestrierungen ermöglicht, die in einer komplexeren Situation zwischen den Fragmenten benötigt werden.Zum Beispiel:

public interface FragmentCommunicator 
{ 
    public void sendMessage (String broadcastMessage); 
    public void takeAction (String name, int action, Fragment frag); 
} 

public class MainActivity extends Activity implements FragmentCommunicator 
{ 
    Fragment fragA; 
    Fragment fragB; 
    ... 
    @Override 
    public void sendMessage (String msg) 
    { 
     if (msg.Contains("Send To fragA")) 
      fragA.receiveMsg(msg); 
     ... 
    } 
    @Override 
    public void takeAction (String name, int action, Fragment frag) 
    { 
    if (action == CLOSE) 
      removeFragment(name, frag); 
     ... 
    } 
} 

public class FragmentA extends Fragment 
{ 
    ... 
@Override 
public void onClick(View v) 
{ 
    FragmentCommunicator inter = (FragmentCommunicator) getActivity(); 
    inter.sendMessage("the txt/information/etc you want to send to fragB");  
} 
} 

public class FragmentB extends Fragment 
{ 
    ... 
    public void receiveMsg (String msg) 
    { 
     textView.setText(msg); 
    } 
} 

Ich habe vergessen, senden Teil von FragmentA. Hoffe, das hilft.

0

developer.android.com

ein Fragment zu ermöglichen, ihre Aktivität zu kommunizieren, können Sie eine Schnittstelle in der Fragment-Klasse definieren und innerhalb der Aktivität umzusetzen. Das Fragment erfasst die Schnittstellenimplementierung während seine onAttach() - Lebenszyklusmethode und kann dann die Schnittstelle Methoden aufrufen, um mit der Aktivität zu kommunizieren.

Beispiel: - http://wiki.workassis.com/android-fragment-communication/

ref: - https://developer.android.com/training/basics/fragments/communicating.html

-1

Es ist eigentlich ziemlich einfach, folgen Sie einfach diesen Schritten:

  1. So Sie die beiden Fragmente A und B erstellt, Jetzt erstellen Sie ihre Gehirne, dh Java-Klassendateien. Lässt sie JClass A nennen (für Fragment A) und JClass B (für Fragment B)

2.You bekam Taste in Ihnen Frag A, so gehen zu JClass A, und dadurch, dass der Benutzer den String Text erhalten und die Taste gedrückt Ereignis wie folgt: // überschreiben Sie einfach die OnCreate-Methode.

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.<name of your fragment A.xml file>,container,false); 

    userInput = (EditText)view.findViewById(R.id.<Id that you gave to EditText field in which user enters text>); 

    Button myButton = (Button)view.findViewById(R.id.<id of your Button>); 
    myButton.setOnClickListener(
      new Button.OnClickListener(){ 
       public void onClick(View v){ 
        JClassB.setText(userInput.getText().toString());/*Replace JClassB with the java class of Fragment B*/ 

       } 
      } 
    ); 

    return view; 
} 
  1. Und schließlich in Ihrem JClass B (Java-Datei für Fragment B):

    public class BottomSectionFrag erweitert Fragment {

    private static TextView userText; 
    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        View view = inflater.inflate(R.layout.fragmentB, container, false); 
        userText = (TextView)view.findViewById(R.id.userText); 
        return view; 
    } 
    public static void setText(String text){ 
        userText .setText(text); 
    
    } 
    

    }

Voila !!

P.S. Dies ist meine erste Post auf StackOverFlow: D

Frieden raus.

0

ich mag die Aktivität, der mittlere Mann zwischen Fragment zu fragment Kommunikation zu sein. aber die andere Sache, die ich mag, ist eine event bus Architektur, die auch Entkopplung bietet.