Senden Sie Daten von Aktivitäten an Fragmente in Android

316

Ich habe zwei Klassen. Erstens ist Aktivität, zweitens ist ein Fragment, wo ich einige habe EditText. In der Aktivität habe ich eine Unterklasse mit asynchroner Aufgabe und in der Methode doInBackgrounderhalte ich ein Ergebnis, das ich in einer Variablen speichere. Wie kann ich diese Variable aus der Unterklasse "Meine Aktivität" an dieses Fragment senden?

user1302569
quelle

Antworten:

660

Aus Aktivität senden Sie Daten mit der Absicht:

Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

und in der Fragment onCreateView-Methode:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}
ρяσssρєя K.
quelle
15
Können Sie ein Objekt an das Fragment übergeben?
Yeahman
63
Hmm, ich bekomme eine NullPointerException, wenn ich anrufegetArguments().getString(key)
Nima G
9
NullPointerException "String strtext setArguments (). GetString (" edttext ");"
Jorgesys
4
Beim Lesen des Bundle-Inhalts in Fragmenten wird das Bundle immer zuerst mit der Methode getArguments in ein Bundle-Objekt empfangen und mit null verglichen. Andernfalls wird die getString-Methode auf null und damit auf die NPE angewendet, wenn kein Bundle übergeben wird. Dadurch werden die Nullzeigerausnahmen vermieden, wenn das Bundle nicht übergeben wird.
Balachandarkm
3
@ Aznix. Es wird nicht empfohlen, einen Konstruktor für ein Fragment zu erstellen.
Azam
108

Sie können auch über das Fragment auf Aktivitätsdaten zugreifen:

Aktivität:

public class MyActivity extends Activity {

    private String myString = "hello";

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

    public String getMyData() {
        return myString;
    }
}

Fragment:

public class MyFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        MyActivity activity = (MyActivity) getActivity();
        String myDataFromActivity = activity.getMyData();
        return view;
    }
}
Ricardas
quelle
78
Diese Lösung integriert eine enge Kopplung zwischen Ihrer Aktivität und Fragment. Verwenden Sie die BundleKlasse besser , um Informationen weiterzugeben. Alternativ können Sie diese getMyData()Methode von einer Schnittstelle erben und implementieren lassen und Fragmentprüfen, ob getActivity instanceofdie Schnittstelle zurückgibt onAttach().
Rudi Kershaw
1
Diese Lösung ist am besten für mich. Auch wenn myString öffentlich ist, haben Sie nicht getMyData () Methode deklariert
Burak Öztürk
1
Die aktuell akzeptierte Antwort gibt eine Nullzeigerausnahme zurück. Dies sollte die akzeptierte Antwort sein
Richmond
9
Dies sollte nicht die akzeptierte Antwort sein. Die enge Kupplung ist leicht vermeidbar. Dies ist im Allgemeinen eine schlechte Idee und macht das Fragment unbrauchbar. Es kann auch sein, dass es kein Fragment enthält, wenn Sie es nur an eine Aktivität gebunden verwenden. Das Fragment kann nicht für andere Aktivitäten wiederverwendet werden.
Martin Marconcini
51

Ich habe hier auf stackoverflow.com viele Antworten gefunden, aber dies ist definitiv die richtige Antwort von:

"Senden von Daten von Aktivität zu Fragment in Android".

Aktivität:

        Bundle bundle = new Bundle();
        String myMessage = "Stackoverflow is cool!";
        bundle.putString("message", myMessage );
        FragmentClass fragInfo = new FragmentClass();
        fragInfo.setArguments(bundle);
        transaction.replace(R.id.fragment_single, fragInfo);
        transaction.commit();

Fragment:

Lesen des Wertes im Fragment

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Bundle bundle = this.getArguments();
        String myValue = bundle.getString("message");
        ...
        ...
        ...
        }

oder nur

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        String myValue = this.getArguments().getString("message");
        ...
        ...
        ...
        }
Jorgesys
quelle
Ich denke, das ist nicht der beste Ansatz, um onQueryTextSubmit-Suchergebnisse in einer ListView zu aktualisieren, die in einem Fragment verschachtelt ist (wenn jemand schnell tippt, sendet er die Argumente zweimal pro Sekunde).
Martin Pfeffer
1
Was ist mit Object insted von string oder int?
Dario
2
@Jorgesys Was ist mit dieser Lösung? developer.android.com/training/basics/fragments/…
yozhik
22

Diese Antwort ist möglicherweise zu spät. aber es wird für zukünftige Leser nützlich sein.

Ich habe einige Kriterien. Ich habe für die Auswahl der Datei aus Absicht codiert. und ausgewählte Datei, die zur weiteren Verarbeitung an ein bestimmtes Fragment übergeben werden soll. Ich habe viele Fragmente mit der Funktionalität der Dateiauswahl. Zu dieser Zeit ist es ziemlich ekelhaft, jedes Mal den Zustand zu überprüfen, das Fragment zu erhalten und den Wert zu übergeben. Also habe ich beschlossen, den Wert über die Schnittstelle zu übergeben.

Schritt 1: Erstellen Sie die Schnittstelle für die Hauptaktivität.

   public interface SelectedBundle {
    void onBundleSelect(Bundle bundle);
   }

Schritt 2: Erstellen Sie die SelectedBundle-Referenz für dieselbe Aktivität

   SelectedBundle selectedBundle;

Schritt 3: Erstellen Sie die Methode in derselben Aktivität

   public void setOnBundleSelected(SelectedBundle selectedBundle) {
       this.selectedBundle = selectedBundle;
   }

Schritt 4: Notwendigkeit , den SelectedBundle Bezug zu initialisieren , die alles Fragment Notwendigkeit Filepicker functionality.You Ort dieser Code auf dem Fragmente sind onCreateView(..)Verfahren

    ((MainActivity)getActivity()).setOnBundleSelected(new MainActivity.SelectedBundle() {
          @Override
         public void onBundleSelect(Bundle bundle) {
            updateList(bundle);
        }
     });

Schritt 5: meinem Fall muss ich das Bild Uri von HomeActivity an fragment übergeben. Also habe ich diese Funktionalität für die onActivityResult-Methode verwendet.

onActivityResult aus der MainActivity übergeben Sie die Werte über die Schnittstelle an die Fragmente.

Hinweis: Ihr Fall kann anders sein. Sie können es von jedem Ort aus von Ihrer HomeActivity aus aufrufen.

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent  data) {
       selectedBundle.onBundleSelect(bundle);
  }

Das ist alles. Implementieren Sie jedes benötigte Fragment in der FragmentClass. Du bist großartig. du hast gemacht. BEEINDRUCKEND...

Noorul
quelle
15

Die Grundidee der Verwendung von Fragmenten (F) besteht darin, wiederverwendbare, selbsttragende UI-Komponenten in Android-Anwendungen zu erstellen. Diese Fragmente sind in Aktivitäten enthalten und es gibt eine übliche (beste) Möglichkeit, Kommunikationspfade von A -> F und FA zu erstellen. Es ist ein Muss, zwischen FF über eine Aktivität zu kommunizieren, da dann nur die Fragmente entkoppelt und selbsttragend werden.

Das Übergeben von Daten von A -> F ist also dasselbe wie von ρяσsρєя K. erklärt. Zusätzlich zu dieser Antwort können wir nach dem Erstellen der Fragmente innerhalb einer Aktivität auch Daten an die Fragmente übergeben, die Methoden in Fragmenten aufrufen.

Zum Beispiel:

    ArticleFragment articleFrag = (ArticleFragment)
                    getSupportFragmentManager().findFragmentById(R.id.article_fragment);
    articleFrag.updateArticleView(position);
diyoda_
quelle
15

Der beste und bequemste Ansatz ist das Aufrufen der Fragmentinstanz und das Senden von Daten zu diesem Zeitpunkt. Jedes Fragment verfügt standardmäßig über eine Instanzmethode

Beispiel: Wenn Ihr Fragmentname MyFragment lautet

Sie werden Ihr Fragment also aus einer Aktivität wie dieser aufrufen:

getSupportFragmentManager().beginTransaction().add(R.id.container, MyFragment.newInstance("data1","data2"),"MyFragment").commit();

* R.id.container ist eine ID meines FrameLayout

In MyFragment.newInstance ("data1", "data2") können Sie also Daten an ein Fragment senden, und in Ihrem Fragment erhalten Sie diese Daten in MyFragment newInstance (String param1, String param2).

public static MyFragment newInstance(String param1, String param2) {
        MyFragment fragment = new MyFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

und dann erhalten Sie in der onCreate- Fragmentmethode die Daten:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

Jetzt haben mParam1 Daten1 und mParam2 Daten2

Jetzt können Sie dieses mParam1 und mParam2 in Ihrem Fragment verwenden.

Pre_hacker
quelle
Was ist R.id.container hier? Meinten Sie R.id.container_current, dies ist ein int-Wert.
Shaurya Uppal
@s * R.id.container ist eine ID meines FrameLayout
Pre_hacker
Bisher die beste Erklärung, die ich je gefunden habe, um Daten zum Hinzufügen / Ersetzen von Fragmenten mit Fragment Manager zu übergeben. Funktioniert wie ein Juwel! Vielen Dank!
Sam
benutzte R.id.nav_host_fragment anstelle von R.id.container
Bahaa Hany
10

Ich möchte für Anfänger hinzufügen, dass der Unterschied zwischen den beiden am besten bewerteten Antworten hier durch die unterschiedliche Verwendung eines Fragments gegeben ist.

Wenn Sie das Fragment in der Java-Klasse verwenden, in der Sie die Daten haben, die Sie übergeben möchten, können Sie die erste Antwort anwenden, um Daten zu übergeben:

Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

Wenn Sie jedoch beispielsweise den von Android Studio angegebenen Standardcode für Fragmente mit Registerkarten verwenden, funktioniert dieser Code nicht.

Dies funktioniert auch dann nicht, wenn Sie das Standard-PlaceholderFragment durch Ihre FragmentClasses ersetzen und den FragmentPagerAdapter an die neue Situation anpassen, indem Sie einen Schalter für getItem () und einen weiteren Schalter für getPageTitle () hinzufügen (wie hier gezeigt ).

Warnung: Der oben erwähnte Clip enthält Codefehler, die ich später hier erläutere. Sie ist jedoch hilfreich, um zu sehen, wie Sie vom Standardcode zum bearbeitbaren Code für Fragmente mit Registerkarten wechseln. Der Rest meiner Antwort ist viel sinnvoller, wenn Sie die Java-Klassen und XML-Dateien aus diesem Clip betrachten (repräsentativ für die erste Verwendung von Fragmenten mit Registerkarten durch ein Anfängerszenario).

Der Hauptgrund, warum die am besten bewertete Antwort auf dieser Seite nicht funktioniert, ist, dass in diesem Standardcode für Fragmente mit Registerkarten die Fragmente in einer anderen Java-Klasse verwendet werden: FragmentPagerAdapter!

Um die Daten zu senden, sind Sie versucht, ein Bundle in der MotherActivity zu erstellen und es im FragmentPagerAdapter mit der Antwort Nr. 2 zu übergeben.

Nur das ist wieder falsch. ( Wahrscheinlich könnten Sie es so machen, aber es ist nur eine Komplikation, die nicht wirklich benötigt wird ).

Ich denke, der richtige / einfachere Weg besteht darin, die Daten mit der Antwort Nr. 2 direkt an das betreffende Fragment zu übergeben. Ja, es wird eine enge Kopplung zwischen der Aktivität und dem Fragment geben, ABER für Fragmente mit Registerkarten, was irgendwie erwartet wird. Ich würde Ihnen sogar raten, die Fragmente mit Registerkarten in der Java-Klasse MotherActivity zu erstellen (als Unterklassen, da sie niemals außerhalb der MotherActivity-Klasse verwendet werden). Es ist ganz einfach, in der Java-Klasse MotherActivity so viele Fragmente hinzuzufügen, wie Sie benötigen:

 public static class Tab1 extends Fragment {

    public Tab1() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
        return rootView;
    }
}.

Um Daten aus der MotherActivity an ein solches Fragment zu übergeben, müssen Sie private Strings / Bundles über der Aktivität onCreate Ihrer Mutter erstellen. Diese können Sie mit den Daten füllen, die Sie an die Fragmente übergeben möchten, und diese über a weitergeben Methode, die nach dem onCreate erstellt wurde (hier getMyData () genannt).

public class MotherActivity extends Activity {

    private String out;
    private Bundle results;

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

       // for example get a value from the previous activity
        Intent intent = getIntent();
        out = intent.getExtras().getString("Key");

    }

    public Bundle getMyData() {
        Bundle hm = new Bundle();
        hm.putString("val1",out);
        return hm;
    }
}

Und dann verwenden Sie in der Fragmentklasse getMyData:

public static class Tab1 extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        public Tab1() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
            TextView output = (TextView)rootView.findViewById(R.id.your_id_for_a_text_view_within_the_layout);

            MotherActivity activity = (MotherActivity)getActivity();

            Bundle results = activity.getMyData();
            String value1 = results.getString("val1");

            output.setText(value1);
            return rootView;
        }
    }

Wenn Sie Datenbankabfragen haben, empfehle ich Ihnen, diese in MotherActivity auszuführen (und ihre Ergebnisse als Strings / Integers zu übergeben, die wie oben gezeigt an Schlüssel in einem Bundle angehängt sind), da Ihre Syntax innerhalb der Fragmente mit Registerkarten komplexer wird (dies wird zu getActivity) () zum Beispiel, und getIntent wird zu getActivity (). getIntent), aber Sie haben auch die Möglichkeit, zu tun, was Sie möchten.

Mein Rat für Anfänger ist, sich auf kleine Schritte zu konzentrieren. Holen Sie sich zunächst die Absicht, eine sehr einfache Aktivität mit Registerkarten zu öffnen, ohne Daten zu übergeben. Funktioniert es? Öffnet es die erwarteten Registerkarten? Wenn nicht, warum?

Beginnen Sie damit, und wenden Sie Lösungen wie die in diesem Clip vorgestellten an, um festzustellen , was fehlt. Für diesen bestimmten Clip wird die Datei mainactivity.xml nie angezeigt. Das wird Sie sicherlich verwirren. Wenn Sie jedoch darauf achten, werden Sie feststellen, dass beispielsweise der Kontext (tools: context) in den XML-Fragmentdateien falsch ist. Jedes Fragment-XML muss auf die richtige Fragmentklasse (oder Unterklasse mit dem Trennzeichen $) verweisen.

Sie werden auch sehen, dass Sie in der Java-Klasse der Hauptaktivität tabLayout.setupWithViewPager (mViewPager) hinzufügen müssen - direkt nach der Zeile TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); Ohne diese Zeile ist Ihre Ansicht nicht mit den XML-Dateien der Fragmente verknüpft, sondern zeigt NUR die XML-Datei der Hauptaktivität an.

Zusätzlich zu der Zeile in der Java-Klasse der Hauptaktivität müssen Sie in der XML-Datei der Hauptaktivität die Registerkarten an Ihre Situation anpassen (z. B. TabItems hinzufügen oder entfernen). Wenn Sie im XML der Hauptaktivität keine Registerkarten haben, haben Sie möglicherweise nicht den richtigen Aktivitätstyp ausgewählt, als Sie ihn erstellt haben (neue Aktivität - Aktivität mit Registerkarten).

Bitte beachten Sie, dass ich in den letzten 3 Absätzen über das Video spreche! Wenn ich also XML für Hauptaktivität sage, ist es das XML für Hauptaktivität im Video, in Ihrer Situation die MotherActivity XML-Datei.

Adrian Stoica
quelle
8

Wenn Sie einen Verweis auf das (konkrete Unterklasse von) Fragment an die asynchrone Aufgabe übergeben, können Sie direkt auf das Fragment zugreifen.

Einige Möglichkeiten, die Fragmentreferenz an die asynchrone Aufgabe zu übergeben:

  • Wenn Ihre asynchrone Aufgabe eine vollwertige Klasse ( class FooTask extends AsyncTask) ist, übergeben Sie Ihr Fragment an den Konstruktor.
  • Wenn Ihre asynchrone Aufgabe eine innere Klasse ist, deklarieren Sie einfach eine endgültige Fragmentvariable in dem Bereich, in dem die asynchrone Aufgabe definiert ist, oder als Feld der äußeren Klasse. Sie können von der inneren Klasse aus darauf zugreifen.
Martin
quelle
Ihre Antwort scheint mir ziemlich legitim zu sein. Können Sie etwas mehr erweitern, indem Sie einen Beispielcode bereitstellen?
Leon Armstrong
5

Sehr alter Beitrag, trotzdem wage ich es, eine kleine Erklärung hinzuzufügen, die für mich hilfreich gewesen wäre.

Technisch gesehen können Sie Mitglieder eines beliebigen Typs in einem Fragment direkt aus der Aktivität festlegen.
Warum also Bundle?
Der Grund ist sehr einfach: Bundle bietet eine einheitliche Vorgehensweise:
- Erstellen / Öffnen von Fragmenten
- Neukonfiguration (Bildschirmrotation) - Hinzufügen eines anfänglichen / aktualisierten Bundles zu outState in onSaveInstanceState ()
- Wiederherstellung der App nach dem Sammeln von Müll im Hintergrund ( wie bei der Neukonfiguration).

Sie können (wenn Sie Experimente mögen) in einfachen Situationen eine Problemumgehung erstellen, aber der Bundle-Ansatz sieht keinen Unterschied zwischen einem Fragment und eintausend auf einem Backstack - er bleibt einfach und unkompliziert.
Deshalb ist die Antwort von @Elenasys die eleganteste und universellste Lösung.
Und deshalb ist die Antwort gegeben @ Martin hat Tücken

sberezin
quelle
5

Manchmal können Sie Absicht in Ihrer Aktivität erhalten und müssen die Informationen an Ihr Arbeitsfragment weitergeben.
Die angegebenen Antworten sind in Ordnung, wenn Sie das Fragment starten müssen, aber wenn es noch funktioniert, setArguments()ist es nicht sehr nützlich.
Ein weiteres Problem tritt auf, wenn die übergebenen Informationen zu einer Interaktion mit Ihrer Benutzeroberfläche führen. In diesem Fall können Sie so etwas nicht aufrufen, myfragment.passData()da Android schnell erkennt , dass nur der Thread, der die Ansicht erstellt hat, mit ihm interagieren kann.

Mein Vorschlag ist also, einen Empfänger zu verwenden. Auf diese Weise können Sie Daten von überall senden, einschließlich der Aktivität. Die Aufgabe wird jedoch im Kontext des Fragments ausgeführt.

In Ihrem Fragment onCreate():

protected DataReceiver dataReceiver;
public static final String REC_DATA = "REC_DATA";

@Override
public void onCreate(Bundle savedInstanceState) {


    data Receiver = new DataReceiver();
    intentFilter = new IntentFilter(REC_DATA);

    getActivity().registerReceiver(dataReceiver, intentFilter);
}

private class DataReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        int data= intent.getIntExtra("data", -1);

        // Do anything including interact with your UI
    }
}

In Ihrer Aktivität:

// somewhere
Intent retIntent = new Intent(RE_DATA);
retIntent.putExtra("data", myData);
sendBroadcast(retIntent);
fralbo
quelle
4

Der bessere Ansatz zum Senden von Daten von der Aktivitätsklasse an das Fragment ist die Übergabe über Setter-Methoden. Mögen

FragmentClass fragmentClass = new FragmentClass();
fragmentClass.setMyList(mylist);
fragmentClass.setMyString(myString);
fragmentClass.setMyMap(myMap);

und holen Sie sich diese Daten einfach aus der Klasse.

ssi-anik
quelle
So übergeben Sie Daten von Fragment zu Fragment wie stackoverflow.com/questions/32953477/pass-data-to-fragment
Hoo
Dies ist nicht sehr praktisch, wenn Sie auch andere, zuvor festgelegte Extra's
Gerard
Wenn diese Daten auf ein Feld in Ihrem Fragment festgelegt werden müssen und sie noch nicht sichtbar (initialisiert) sind, erhalten Sie NPE.
Yozhik
Ich habe wahrscheinlich vor 3 Jahren aufgehört, mit Android zu arbeiten. Diese Dinge sind heutzutage möglicherweise veraltet.
ssi-anik
4

Von Activitysenden Sie Daten mit Bundle als:

Bundle bundle = new Bundle();
bundle.putString("data", "Data you want to send");

// Your fragment
MyFragment obj = new MyFragment();
obj.setArguments(bundle);

Und in der FragmentonCreateView-Methode erhalten Sie die Daten:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
    String data = getArguments().getString("data");// data which sent from activity  
    return inflater.inflate(R.layout.myfragment, container, false);
}
Vijay
quelle
3

Wenn ein activitymuss eine macht fragmenteine Aktion nach der Initialisierung durchführt, ist der einfachste Weg , die durch mit activityinvoke eines Verfahrens auf der fragmentInstanz. In der fragment, fügen Sie eine Methode:

public class DemoFragment extends Fragment {
  public void doSomething(String param) {
      // do something in fragment
  }
}

und dann in der activityerhalten Sie Zugriff auf die fragmentmit dem fragmentManager und rufen Sie die method:

public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DemoFragment fragmentDemo = (DemoFragment) 
            getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);
        fragmentDemo.doSomething("some param");
    }
}

und dann activitykann der direkt mit dem kommunizieren, fragmentindem er dies aufruft method.


quelle
1
Das ist wirklich schön, in dem Sinne, dass Sie onCreateViewim Fragment keine Methode eingeben möchten . war wirklich hilfreich
Young Emil
2

bin gerade über diese Frage gestolpert, während die meisten der oben genannten Methoden funktionieren werden. Ich möchte nur hinzufügen, dass Sie die Ereignisbusbibliothek verwenden können , insbesondere in Szenarien, in denen die Komponente (Aktivität oder Fragment) nicht erstellt wurde. Sie eignet sich für alle Größen von Android-Projekten und viele Anwendungsfälle. Ich habe es persönlich in mehreren Projekten verwendet, die ich im Playstore habe.

Joshua Majebi
quelle
1

Sie können eine öffentliche statische Methode in Fragment erstellen, wobei Sie eine statische Referenz dieses Fragments erhalten und dann Daten an diese Funktion übergeben und diese Daten auf Argument in derselben Methode setzen und Daten über getArgument auf oncreate Methode des Fragments abrufen und diese Daten auf lokal setzen Variablen.

M.Noman
quelle
1

Die intelligenteste und bewährte Methode zum Übergeben von Daten zwischen Fragmenten und Aktivitäten besteht darin, Variablen zu erstellen. Beispiel:

class StorageUtil {
  public static ArrayList<Employee> employees;
}

Um dann Daten vom Fragment an die Aktivität zu übergeben, tun wir dies in der onActivityCreated-Methode:

//a field created in the sending fragment
ArrayList<Employee> employees;

@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
         employees=new ArrayList();

       //java 7 and above syntax for arraylist else use employees=new ArrayList<Employee>() for java 6 and below

     //Adding first employee
        Employee employee=new Employee("1","Andrew","Sam","1984-04-10","Male","Ghanaian");
        employees.add(employee);

      //Adding second employee
       Employee employee=new Employee("1","Akuah","Morrison","1984-02-04","Female","Ghanaian");
         employees.add(employee);

        StorageUtil.employees=employees;
    }

Jetzt können Sie den Wert von StorageUtil.employees von überall her abrufen. Viel Glück!

Andrew Sam
quelle
1

Verwenden Sie die folgende Schnittstelle, um zwischen Aktivität und Fragment zu kommunizieren

public interface BundleListener {
    void update(Bundle bundle);
    Bundle getBundle();
}

Oder verwenden Sie diesen generischen Listener für die bidirektionale Kommunikation über die Schnittstelle

 /**
 * Created by Qamar4P on 10/11/2017.
 */
public interface GenericConnector<T,E> {
    T getData();
    void updateData(E data);
    void connect(GenericConnector<T,E> connector);
}

Fragment-Show-Methode

public static void show(AppCompatActivity activity) {
        CustomValueDialogFragment dialog = new CustomValueDialogFragment();
        dialog.connector = (GenericConnector) activity;
        dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
    }

Sie können Ihren Kontext auch GenericConnectorin onAttach(Context)umwandeln

in Ihrer Tätigkeit

CustomValueDialogFragment.show(this);

in deinem Fragment

...
@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        connector.connect(new GenericConnector() {
            @Override
            public Object getData() {
                return null;
            }

            @Override
            public void updateData(Object data) {

            }

            @Override
            public void connect(GenericConnector connector) {

            }
        });
    }
...
    public static void show(AppCompatActivity activity, GenericConnector connector) {
            CustomValueDialogFragment dialog = new CustomValueDialogFragment();
            dialog.connector = connector;
            dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
        }

Hinweis: Verwenden Sie es niemals "".toString().toString().toString();so.

Qamar
quelle
0

Meine Lösung besteht darin, eine statische Methode in das Fragment zu schreiben:

public TheFragment setData(TheData data) {
    TheFragment tf = new TheFragment();
    tf.data = data;
    return tf;
}

Auf diese Weise bin ich sicher, dass sich alle Daten, die ich benötige, im Fragment befinden, bevor andere mögliche Vorgänge ausgeführt werden, die möglicherweise erforderlich sind, um damit zu arbeiten. Auch sieht es meiner Meinung nach sauberer aus.

Matteo
quelle
1
Wenn TheData nicht threadsicher ist, werden Sie nicht unbedingt vor Threadproblemen geschützt, wenn Sie es statisch machen. Sei vorsichtig damit. Static ist von Natur aus nicht threadsicher.
Martin Marconcini
0

Bei der Verwendung der neuesten Navigationsarchitekturkomponente ist ein ähnliches Problem aufgetreten. Versuchte den gesamten oben genannten Code mit der Übergabe eines Bündels von meiner aufrufenden Aktivität an Fragment.

Die beste Lösung, die den neuesten Entwicklungstrends in Android folgt, ist die Verwendung des Ansichtsmodells (Teil von Android Jetpack).

Erstellen und Initialisieren einer ViewModel-Klasse in der übergeordneten Aktivität. Beachten Sie, dass dieses ViewModel für die Aktivität und das Fragment freigegeben werden muss.

Initialisieren Sie nun in onViewCreated () des Fragments dasselbe ViewModel und richten Sie Observer ein, um die ViewModel-Felder abzuhören.

Hier finden Sie bei Bedarf ein hilfreiches, ausführliches Tutorial.

https://medium.com/mindorks/how-to-communicate-between-fragments-and-activity-using-viewmodel-ca733233a51c

devDeejay
quelle
-4

Deklarieren Sie in Ihrer Aktivität eine statische Variable

public static HashMap<String,ContactsModal> contactItems=new HashMap<String, ContactsModal>();

Dann folgen Sie in Ihrem Fragment gerne

ActivityName.contactItems.put(Number,contactsModal);
Dv Keerthi
quelle
Es wird funktionieren, aber nicht empfohlen. Da statische Mitglieder im Speicher bleiben, es sei denn, die App wird aus den letzten Apps zwangsweise geschlossen. In einem solchen Fall sollten Sie statische Elemente nur dann verwenden, wenn Sie sie für viele Aktivitäten in der gesamten App benötigen.
M Shaban Ali