it-swarm-eu.dev

Kommunikation zwischen einem Fragment und einer Aktivität - Best Practices

Diese Frage dient hauptsächlich dazu, Meinungen zur optimalen Handhabung meiner App einzuholen. Ich habe drei Fragmente, die von einer Aktivität behandelt werden. Fragment A hat ein anklickbares Element, das Foto und Fragment B hat 4 anklickbare Elemente, die Schaltflächen. Das andere Fragment zeigt nur Details an, wenn auf das Foto geklickt wird. Ich verwende ActionBarSherlock. 

Screen shot

Die Vorwärts- und Zurück-Tasten müssen das Foto in die nächste bzw. vorherige Pose ändern. Ich konnte das Foto und die Knöpfe in demselben Fragment halten, wollte sie jedoch getrennt halten, falls ich sie in einem Tablet neu anordnen wollte. 

Ich brauche einen Rat - sollte ich die Fragmente A und B kombinieren? Wenn nicht, muss ich herausfinden, wie eine Schnittstelle für 3 anklickbare Elemente implementiert wird. 

Ich habe überlegt, Roboguice zu verwenden, aber ich erweitere bereits die Verwendung von SherlockFragmentActivity. Ich sah die Erwähnung von Otto, aber ich sah keine guten Tutorials, wie man sie in ein Projekt einfügt. Was ist Ihrer Meinung nach die beste Designpraxis? 

Ich brauche auch Hilfe, um herauszufinden, wie man zwischen einem Fragment und einer Aktivität kommuniziert. Ich möchte einige Daten in der Anwendung "global" halten, z. B. die Posen-ID. Gibt es einen Beispielcode, den ich neben den Informationen des Android-Entwicklers sehen kann? Das ist gar nicht so hilfreich. 

Übrigens, ich speichere bereits alle Informationen zu jeder Pose in einer SQLite-Datenbank. Das ist der leichte Teil. 

49
Kristy Welsh

Der einfachste Weg, um zwischen Ihrer Aktivität und Fragmenten zu kommunizieren, ist die Verwendung von Schnittstellen. Die Idee besteht im Wesentlichen darin, eine Schnittstelle innerhalb eines gegebenen Fragments A zu definieren und die Aktivität diese Schnittstelle implementieren zu lassen.

Sobald diese Schnittstelle implementiert wurde, können Sie mit der Methode, die sie überschreibt, alles tun, was Sie möchten.

Der andere wichtige Teil der Schnittstelle besteht darin, dass Sie die abstrakte Methode aus Ihrem Fragment aufrufen und daran denken müssen, sie in Ihre Aktivität umzuwandeln. Eine ClassCastException sollte abgefangen werden, wenn sie nicht ordnungsgemäß ausgeführt wird.

Es gibt ein gutes Tutorial auf Simple Developer Blog , wie man genau so etwas macht.

Ich hoffe das war hilfreich für dich!

70
Eenvincible

Die empfohlene Methode zur Kommunikation zwischen Fragmenten ist die Verwendung von Callbacks\Listeners, die von Ihrer Hauptaktivität verwaltet werden.

Ich denke, der Code auf dieser Seite ist ziemlich klar: http://developer.Android.com/training/basics/fragments/communicating.html

Sie können auch auf die IO 2012 Schedule-App verweisen, die als De-facto-Referenz-App konzipiert wurde. Sie finden es hier: http://code.google.com/p/iosched/

Hier ist auch eine SO - Frage mit guten Informationen: So übergeben Sie Daten zwischen Fragmenten

23
Booger

Es wird durch Rückrufschnittstelle implementiert: Zuerst müssen wir eine Schnittstelle erstellen:

public interface UpdateFrag {
     public void updatefrag();
    }

In Aktivität machen Sie den folgenden Code:

UpdateFrag updatfrag ;
public void updateApi(UpdateFrag listener) {
        updatfrag = listener;
   }

von Ereignis, von dem aus der Rückruf in Aktivität ausgelöst werden muss:

updatfrag.updatefrag();

In Fragment implementieren Sie die Schnittstelle in CreateView mit folgendem Code:

 ((Home)getActivity()).updateApi(new UpdateFrag() {
                @Override
                public void updatefrag() {
                   .....your stuff......
                }
            });
9
Jyoti

Ich habe eine Anmerkungsbibliothek erstellt, die die Besetzung für Sie erledigen kann. Schauen Sie sich das an . https://github.com/zeroarst/callbackfragment/

@CallbackFragment
public class MyFragment extends Fragment {

    @Callback
    interface FragmentCallback {
       void onClickButton(MyFragment fragment);
    }    
    private FragmentCallback mCallback;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt1
                mCallback.onClickButton(this);
                break;
            case R.id.bt2
                // Because we give mandatory = false so this might be null if not implemented by the Host.
                if (mCallbackNotForce != null)
                mCallbackNotForce.onClickButton(this);
                break;
        }
    }
}

Es generiert dann eine Unterklasse Ihres Fragments. Und fügen Sie es einfach zu FragmentManager hinzu.

public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback {

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

        getSupportFragmentManager().beginTransaction()
            .add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), "MY_FRAGM")
            .commit();
    }

    Toast mToast;

    @Override
    public void onClickButton(MyFragment fragment) {
        if (mToast != null)
            mToast.cancel();
        mToast = Toast.makeText(this, "Callback from " + fragment.getTag(), Toast.LENGTH_SHORT);
        mToast.show();
    }
}
4
Arst

Es gibt verschiedene Möglichkeiten, zwischen Aktivitäten, Fragmenten, Diensten usw. zu kommunizieren. Die naheliegendste ist die Kommunikation über Schnittstellen. Es ist jedoch keine produktive Art zu kommunizieren. Sie müssen die Zuhörer usw. implementieren.

Mein Vorschlag ist, einen Event-Bus zu verwenden. Der Ereignisbus ist eine Implementierung eines Publish/Subscribe-Musters.

Sie können Ereignisse in Ihrer Aktivität abonnieren und diese Ereignisse dann in Ihren Fragmenten usw. posten.

Hier in meinem Blog-Beitrag finden Sie weitere Details zu diesem Muster und ein Beispielprojekt , um die Verwendung anzuzeigen.

2
Gunhan

Ich bin mir nicht sicher, ob ich wirklich verstanden habe, was Sie tun möchten. Die empfohlene Methode für die Kommunikation zwischen Fragmenten ist jedoch die Verwendung von Rückrufen mit der Aktivität, niemals direkt zwischen Fragmenten. Siehe hier http://developer.Android.com/training/basics/fragments/communicating.html

1
alex

Um zwischen einem Activity und einem Fragments zu kommunizieren, gibt es mehrere Möglichkeiten, aber nach vielem Lesen und vielen Erfahrungen habe ich herausgefunden, dass es auf diese Weise wieder aufgenommen werden kann:

  • Activity möchte mit dem Kind Fragment = kommunizieren.> Schreiben Sie einfach öffentliche Methoden in Ihre Fragment-Klasse, und lassen Sie sie von Activity aufgerufen werden
  • Fragment möchte mit dem Elternteil kommunizieren Activity => Dies erfordert etwas mehr Arbeit, da der offizielle Android-Link https://developer.Android.com/training/basics/fragments/communicating einen Vorschlag macht Eine großartige Idee, ein interface zu definieren, das von Activity implementiert wird und einen Vertrag für jedes Activity erstellt, das mit diesem Fragment kommunizieren möchte. Wenn Sie beispielsweise FragmentA haben, das mit einem beliebigen activity, das es enthält, kommunizieren möchte, definieren Sie das FragmentAInterface, mit dem festgelegt wird, welche Methode das FragmentA für das activities aufrufen kann, das es verwendet.
  • Ein Fragment möchte mit anderen Fragment => kommunizieren. Dies ist der Fall, in dem die komplizierteste Situation auftritt. Da Sie möglicherweise Daten von FragmentA an FragmentB und viceversa übergeben müssen, könnte dies dazu führen, dass zwei Schnittstellen definiert werden, FragmentAInterface, die von FragmentB und FragmentAInterface implementiert werden und von FragmentA implementiert werden. Das wird alles unordentlich machen. Und stellen Sie sich vor, Sie hätten noch ein paar Fragments vor Ort, und sogar das übergeordnete activity möchte mit ihnen kommunizieren. Nun, dieser Fall ist der perfekte Moment, um ein gemeinsames ViewModel für das activity und dessen fragments festzulegen. Mehr Infos hier https://developer.Android.com/topic/libraries/architecture/viewmodel . Grundsätzlich müssen Sie eine SharedViewModel-Klasse definieren, die alle Daten enthält, die Sie zwischen dem activity und dem fragments freigeben möchten, die Daten zwischen ihnen austauschen müssen.

Der ViewModel-Fall macht die Sache am Ende ziemlich einfacher, da Sie keine zusätzliche Logik hinzufügen müssen, die den Code schmutzig und unordentlich macht. Außerdem können Sie die Erfassung (durch Aufrufe einer SQLite-Datenbank oder einer API) von Daten von Controller (activities und fragments) trennen.

Sie können eine öffentliche Schnittstelle mit einer Funktionsdeklaration im Fragment deklarieren und die Schnittstelle in der Aktivität implementieren. Dann können Sie die Funktion aus dem Fragment aufrufen. 

0
Jacob Abraham

Ich benutze Intents, um Aktionen zurück zur Hauptaktivität zu bringen. Die Hauptaktivität besteht darin, diese zu hören, indem onNewIntent (Intent Intent) überschrieben wird. Die Hauptaktivität übersetzt diese Aktionen beispielsweise in die entsprechenden Fragmente.

So kannst du so etwas machen:

public class MainActivity extends Activity  {

    public static final String INTENT_ACTION_SHOW_FOO = "show_foo";
    public static final String INTENT_ACTION_SHOW_BAR = "show_bar";


   @Override
   protected void onNewIntent(Intent intent) {
        routeIntent(intent);
   }

  private void routeIntent(Intent intent) {
       String action = intent.getAction();
       if (action != null) {               
            switch (action) {
            case INTENT_ACTION_SHOW_FOO:
                // for example show the corresponding fragment
                loadFragment(FooFragment);
                break;
            case INTENT_ACTION_SHOW_BAR:
                loadFragment(BarFragment);
                break;               
        }
    }
}

Dann in einem Fragment, um das Foo-Fragment anzuzeigen:

Intent intent = new Intent(context, MainActivity.class);
intent.setAction(INTENT_ACTION_SHOW_FOO);
// Prevent activity to be re-instantiated if it is already running.
// Instead, the onNewEvent() is triggered
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
getContext().startActivity(intent);
0
Pepster