2013-07-03 24 views
9

Ich habe eine Activity mit mehreren Fragment s. Ich möchte eine DialogFragment zeigen oder eine andere Fragment von einem der Fragment s öffnen. Ich weiß, dass ein Activity derjenige sein sollte, der damit beauftragt ist, Fragment s zu öffnen, so habe ich stattdessen ein paar Dinge versucht.Aktivität und Fragment Interaktion

FIRST
Ich versuchte getActivity() zu bedienen und warf es so kann ich eine Methode in der Activity nennen eine Fragment jedoch zu zeigen, dies schafft eine Abhängigkeit in der Fragment mit dem Activity und ich würde eine Abhängigkeit zu vermeiden, wie das Hinzufügen wenn möglich.

SECOND
Als nächstes habe ich versucht, einen Hörer die Activity zu benachrichtigen, dass es eine Fragment zeigen sollte. Also habe ich eine Klasse in Activity erstellt, um die Listener-Schnittstelle zu implementieren. Aber ich hatte Probleme, weil ich New MyActivity().new Listener(); verwenden musste, und es würde einen Exception werfen, als ich versuchte, getSupportFragmentManager() zu verwenden, da diese Instanz der Activity nicht initialisiert wird.

DRITTE
Ich habe versucht, dann müssen die Activity den Zuhörer direkt implementieren, die funktioniert, weil dann bin ich nur eine Abhängigkeit mit dem Hörer und nicht die Aktivität. Aber jetzt komme ich zu dem Punkt, wo meine Activity 2 - 4 verschiedene Schnittstellen implementieren wird, was mich zögert, weil es den Zusammenhalt stark reduzieren wird.

So jede mögliche Weise, die ich versucht habe ich scheine in eine Mauer zu laufen und die Schaffung von Abhängigkeiten Ich bin nicht sicher, ich Schaffung werden müssen. Bin ich geschraubt und muss mit einer dieser Optionen gehen? Wenn ja, welche Option wäre am besten? Jede Hilfe oder Vorschläge werden sehr geschätzt.

+0

Es gibt viele Möglichkeiten, es zu tun, ich bevorzuge Dinge so entkoppelt wie möglich, und dafür mag ich einen Event-Bus. Siehe zum Beispiel otto: http://square.github.io/otto/. (Lässt Sie alle Schnittstellen/Listener loswerden. Übergeben Sie Daten, tun Sie es mit starken Typen, tun Sie es in einer übersichtlichen Weise.) –

+0

Es scheint vielversprechend. Ich muss es überprüfen. Danke für den Tipp. –

Antwort

10

Persönlich würde ich sagen, dass Fragmente als wiederverwendbare und modulare Komponenten gedacht werden sollten. Um diese Wiederverwendbarkeit zu gewährleisten, sollten Fragmente nicht viel über ihre übergeordneten Aktivitäten wissen. Aber im Gegenzug müssen Aktivitäten über Fragmente wissen, die sie halten.

So sollte die erste Option meiner Meinung nach nie für den Abhängigkeitsgrund in Betracht gezogen werden, den Sie erwähnten, was einen sehr stark gekoppelten Code verursacht. Über die zweite Option können Fragmente alle Anwendungsfluss- oder UI-bezogenen Entscheidungen delegieren (indem sie ein neues Fragment anzeigen und entscheiden, was zu tun ist, wenn ein fragmentspezifisches Ereignis ausgelöst wird usw.). Daher sollten Ihre Listener/Callbacks fragmentspezifisch sein und daher in Fragmenten deklariert sein. Und die Aktivitäten, die diese Fragmente enthalten, sollten diese Schnittstellen implementieren und entscheiden, was zu tun ist.

Also für mich macht die dritte Option mehr Sinn. Ich glaube, dass Aktivitäten besser lesbar sind, was sie bei bestimmten Rückrufen tun und tun. Aber ja, du hast Recht, deine Aktivität könnte ein Gottobjekt werden.

Vielleicht können Sie Square Otto Projekt überprüfen, wenn Sie nicht mehrere Schnittstellen implementieren möchten. Es ist im Grunde ein Event-Bus.

+0

Danke an Sie und @Charlie Collins, die mich auf die Otto Bibliothek verwiesen haben. Das scheint sehr viel versprechend zu sein und es scheint, als würde es das erreichen, wonach ich suche. Danke an alle für die Hilfe. –

3

Ich denke, Ihre zweite Option ist auf dem richtigen Weg.

In Ihrem Fragment, definieren Sie die Listener-Schnittstelle:

class MyFragment ... 
{ 
    public interface IMyFragmentListenerInterface 
    { 
     void DoSomething(); 
    } 
} 

Haben die Aktivität der Schnittstelle implementieren:

class MyActivity 
{ 
    class MyListener1 implements IMyFragmentListenerInterface { ... } 
} 

Führen Sie den Hörer an das Fragment. Ich mache das gerne im Konstruktor des Fragments, aber das funktioniert nur, wenn Sie Ihre Fragmente vollständig selbst verwalten. Sie können stattdessen eine setListener-Methode zu Ihrem Fragment hinzufügen.

+3

Es gibt ein Problem mit dem 'setListener'-Ansatz: Wenn das Fragment vom Betriebssystem zerstört und neu erstellt wird (unter Verwendung des Standard-Leerkonstruktors), würde der Verweis auf den Listener verloren gehen. Der beste Weg, dies zu erreichen, ist das Einfügen von Code in die 'onAttach'-Methode, um die Elternaktivität des Fragments als Listener zu verbinden, wobei zur Laufzeit überprüft wird, ob die erforderliche Schnittstelle unterstützt wird. Siehe http://developer.android.com/guide/components/fragments.html: "Erstellen von Ereignisrückrufen für die Aktivität". –

0

Haben Sie so etwas wie dies (aus dem Fragment) versucht:

FragmentTransaction ft = 
    getActivity().getSupportFragmentManager().beginTransaction(); 
Fragment prev = 
    getActivity().getSupportFragmentManager().findFragmentByTag("some_name"); 
if (prev != null) { 
    ft.remove(prev); 
} 
ft.addToBackStack(null); 

DialogFragment dialogFragment = DialogFragmentClass.newInstance(); 
dialogFragment.show(ft, "some_name"); 

Lassen Sie mich wissen, cheers.

2

Sie müssen Ihre Daten von Fragment X an Ihre FragmentActivity übergeben, die diese Daten an Ihr Fragment Y weiterleitet. Sie tun dies über eine in Ihrer Fragmentklasse definierte Schnittstelle und instanziieren einen Callback, der in definiert ist onAttach().

Weitere Informationen darüber, wie diese hier zu tun Communication With other Fragments

Schnell Beispiel betrachten Fragment A und Fragment B Fragment A ist eine Liste Fragment und wenn ein Element ausgewählt wird, wird es ändern, was in Fragmente B angezeigt wird Einfach genug, oder?

Definieren Sie zunächst Fragment A als solches.

public class FragmentA extends ListFragment{ 

    //onCreateView blah blah blah 

} 

Und hier ist Fragment B

public class FragmentB extends Fragment{ 

//onCreateView blah blah blah 

} 

Und hier ist mein FragmentActivity, die sie beide

public class MainActivity extends FragmentActivity{ 

//onCreate 
//set up your fragments 

} 

Vermutlich haben Sie so etwas wie dies bereits, jetzt ist hier regieren wird, wie Sie würde fragmenta ändern (das Listenfragment, von dem wir Daten abrufen müssen.

Die wichtigste Überlegung hier ist, dass Ihre Eltern Activity diese Schnittstelle implementiert, sonst erhalten Sie eine Ausnahme. Bei erfolgreicher Implementierung wird jedes Mal, wenn ein Element in Ihrem Listenfragment ausgewählt wird, Ihre Aktivität über ihre Position benachrichtigt. Natürlich können Sie Ihre Schnittstelle mit einer beliebigen Anzahl oder Art von Parametern ändern, in diesem Beispiel geben wir nur unsere ganzzahlige Position ein. Hoffe das klärt ein bisschen Mann, viel Glück.

0

Um ein Maximum an loser Kopplung zu erhalten, können Sie einen Event-Bus wie OTTO von Square oder EventBus von GreenRobot verwenden. Ihre Fragmente können Ereignisse auslösen, die von Ihrer Aktivität behandelt werden und umgekehrt. Das Tolle daran ist, dass die Komponenten (Aktivitäten, Fragmente) nichts miteinander zu tun haben und keine Interfaces oder Callbacks deklariert werden müssen.

Ich benutze es in allen meinen Projekten und es ist robust und hat wenig bis keinen Einfluss auf die Leistung (unter normalen Bedingungen).

2

Schnittstelle erstellen

public interface ListenFromActivity { 
    void doSomethingInFragment(); 
} 

In Aktivitätsklasse refrence von ListenFromActivity Schnittstelle halten

public ListenFromActivity activityListener; 

öffentliche Methode Machen Sie zum Hörer

public void setActivityListener(ListenFromActivity activityListener) { 
     this.activityListener = activityListener; 
    } 

Fügen Sie einige Triggerpunkt in Aktivitätsklasse gesetzt , h ere Ich habe Benutzer-Interaktion

@Override 
    public void onUserInteraction() { 
     super.onUserInteraction(); 

     if (null != activityListener) { 
      activityListener.doSomethingInFragment(); 
     } 
    } 

Jetzt in Fragmente Klasse

Ihr Fragment Interface-Klasse implementieren machen verwendet

public class SomeFragment extends Fragment implements ListenFromActivity 

Android Studio werden Sie auffordern Methode der Schnittstelle in Fragmente zu implementieren

void doSomethingInFragment() 
{//Add your code here 
} 

Endaktivität Teil Zuhörer Instanz Teil wie diese in Fragmente onCreate Methode

((ListnerActivity) getActivity()).setActivityListener(SomeFragment.this); 

DONE !!. Jetzt können Sie die Fragment-Methode aus der Aktivität aufrufen.

Verwandte Themen