So übergeben Sie Werte zwischen Fragmenten


109

Ich bin ziemlich neu in der Verwendung von Fragmenten.

Ich versuche nur, eine einfache Beispielanwendung zu erstellen, die Fragmente verwendet. Mein Szenario ist, ich habe zwei Aktivitäten mit einem Fragment in jeder Aktivität. Das erste Fragment hat einen Edittext und eine Schaltfläche. Das zweite Fragment hat eine Textansicht. Wenn ich einen Namen in den Edittext eingebe und auf die Schaltfläche klicke, sollte die Textansicht im zweiten Fragment den Namen anzeigen, der im Edittext des ersten Fragments eingegeben wurde.

Ich konnte den Wert vom ersten Fragment an seine Aktivität und dann von dieser Aktivität an die zweite Aktivität senden. Wie verwende ich diesen Wert im zweiten Fragment?

Hier ist der Java-Code :::

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Fragment_1 extends Fragment{

    OnFragmentChangedListener mCallback;

    // Container Activity must implement this interface
    public interface OnFragmentChangedListener {
        public void onButtonClicked(String name);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnFragmentChangedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub      

        View view = inflater.inflate(R.layout.fragment_fragment_1, container, false);

        final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName);
        Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi);

        btnSayHi_Fragment.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                String name = edtxtPersonName_Fragment.getText().toString();

                FragmentManager fm = getFragmentManager();
                Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2);

                Activity activity = getActivity();

                if(activity != null)
                {
                    Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show();
                }


                if(f2 != null && f2.isInLayout())
                {
                    f2.setName(name);
                }
                else
                {
                    mCallback.onButtonClicked(name);
                }
            }
        });

        return view;


    }

}

MainActivity.Java

package com.example.fragmentexample;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;

import android.view.Choreographer.FrameCallback;
import android.view.Menu;

public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public void onButtonClicked(String name) {
        // TODO Auto-generated method stub

        Intent i = new Intent(this, SecondActivity.class);
        i.putExtra("", name);
        startActivity(i);
    }

}

SecondActivity.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_second);

        Bundle b = getIntent().getExtras();

        Fragment_2 f2 = new Fragment_2();
        f2.setArguments(b);
    }
}

Fragment_2.Java

package com.example.fragmentexample;

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

public class Fragment_2 extends Fragment{

    View view;
    TextView txtName;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        view = inflater.inflate(R.layout.fragment_fragment_2, container, false);

            // Exception at this line
        String name = getArguments().getString("message");
        txtName = (TextView) view.findViewById(R.id.txtViewResult);
        txtName.setText(name);

        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);       
    }

    public void setName(String name)
    {   
        txtName.setText("Hi " + name);
    }

}

Ich bekomme folgende Ausnahme :::

04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main
04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentexample/com.example.fragmentexample.SecondActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Looper.loop(Looper.java:132)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.main(ActivityThread.java:4123)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invokeNative(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invoke(Method.java:491)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-16 18:10:24.573: E/AndroidRuntime(713):  at dalvik.system.NativeStart.main(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.setContentView(Activity.java:1786)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.performCreate(Activity.java:4397)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 11 more
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.onCreateView(Activity.java:4177)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 21 more

Wie erhalte ich den Wert vom Bundle in SecondActivity.java zum Fragment_2.Java?


Bitte markieren Sie den Teil, wo Sie das Problem bekommen
Nikhil Agrawal

Arbeitslösung auf einfache Weise: stackoverflow.com/a/59332751/10201722
Adil Siddiqui

Antworten:


203

Schritt 1. Daten vom Fragment zur Aktivität senden

Intent intent = new Intent(getActivity().getBaseContext(),
                        TargetActivity.class);
                intent.putExtra("message", message);
                getActivity().startActivity(intent);

Schritt 2. Um diese Daten in Aktivität zu erhalten:

Intent intent = getIntent();
String message = intent.getStringExtra("message");

Schritt 3 . Um Daten von einer Aktivität an eine andere Aktivität zu senden, folgen Sie dem normalen Ansatz

Intent intent = new Intent(MainActivity.this,
                        TargetActivity.class);
                intent.putExtra("message", message);
                startActivity(intent);

Schritt 4 , um diese Daten in Aktivität zu erhalten

     Intent intent = getIntent();
  String message = intent.getStringExtra("message");

Schritt 5. In Aktivität können Sie Daten mit der Absicht an Fragment senden:

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

und in Fragment in Fragment onCreateView-Methode zu empfangen:

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

    return inflater.inflate(R.layout.fragment, container, false);
    }

2
Ich habe Schritt 5 versucht: Ich rufe Listaktivität aus Fragment auf und nachdem ich ein Element aus dieser Aktivität ausgewählt habe, möchte ich in Fragment mit dem ausgewählten Dateinamen zurückkehren. Aber es funktioniert nicht, es gibt mir eine Nullpointer-Ausnahme bei onCreateView. Irgendeine Lösung dazu bitte? Dies ist meine Frage stackoverflow.com/questions/18208771/…
OnkarDhane

Wie setze ich hier ein POJO? bundle.putString("message", "From Activity");
jeet.chanchawat

31
Ist jemand angewidert darüber, wie kompliziert es ist, so etwas zu tun
Ed Lee

1
Genau Eddie, das ist nicht der richtige Weg. Sie sollten Schnittstellen verwenden, um über die Containeraktivität zwischen Fragmenten zu kommunizieren.
Kaveesh Kanwal

In Bezug auf die Verwendung von Schnittstellen zur Kommunikation zwischen Fragmenten: developer.android.com/training/basics/fragments/…
Andre L Torres

49

Wie auf der Entwicklerseite angegeben

Oft möchten Sie, dass ein Fragment mit einem anderen kommuniziert, um beispielsweise den Inhalt basierend auf einem Benutzerereignis zu ändern. Die gesamte Kommunikation von Fragment zu Fragment erfolgt über die zugehörige Aktivität. Zwei Fragmente sollten niemals direkt kommunizieren.

Die Kommunikation zwischen Fragmenten sollte über die zugehörige Aktivität erfolgen.

Lassen Sie uns die folgenden Komponenten haben:

Eine Aktivität hostet Fragmente und ermöglicht die Kommunikation von Fragmenten

FragmentA erstes Fragment, das Daten sendet

FragmentB zweites Fragment, das Daten von FragmentA empfängt

Die Implementierung von FragmentA lautet:

public class FragmentA extends Fragment 
{
    DataPassListener mCallback;
    
    public interface DataPassListener{
        public void passData(String data);
    }

    @Override
    public void onAttach(Context context) 
    {
        super.onAttach(context);
        // This makes sure that the host activity has implemented the callback interface
        // If not, it throws an exception
        try 
        {
            mCallback = (OnImageClickListener) context;
        }
        catch (ClassCastException e) 
        {
            throw new ClassCastException(context.toString()+ " must implement OnImageClickListener");
        }
    }
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
    {
        // Suppose that when a button clicked second FragmentB will be inflated
        // some data on FragmentA will pass FragmentB
        // Button passDataButton = (Button).........
        
        passDataButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (view.getId() == R.id.passDataButton) {
                    mCallback.passData("Text to pass FragmentB");
                }
            }
        });
    }
}

Die Implementierung von MainActivity ist:

public class MainActivity extends ActionBarActivity implements DataPassListener{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        if (findViewById(R.id.container) != null) {
            if (savedInstanceState != null) {
                return;
            }
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new FragmentA()).commit();
        }
    }
    
    @Override
    public void passData(String data) {
        FragmentB fragmentB = new FragmentB ();
        Bundle args = new Bundle();
        args.putString(FragmentB.DATA_RECEIVE, data);
        fragmentB .setArguments(args);
        getFragmentManager().beginTransaction()
            .replace(R.id.container, fragmentB )
            .commit();
    }
}

Die Implementierung von FragmentB ist:

public class FragmentB extends Fragment{
    final static String DATA_RECEIVE = "data_receive";
    TextView showReceivedData;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_B, container, false);
        showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
    }
    
    @Override
    public void onStart() {
        super.onStart();
        Bundle args = getArguments();
        if (args != null) {
            showReceivedData.setText(args.getString(DATA_RECEIVE));
        }
    }
}

Ich hoffe das wird helfen ..


4
Was ist der OnImageClickListener hier? und wie wird es in eine DataPassListener-Variable umgewandelt?
Harsha

Ich fand es ist der "DataPassListener". Ich habe es zum Laufen gebracht, aber nur zu finden, weil jedes Mal, wenn auf die Schaltfläche geklickt wird, die Daten gesendet werden. Wenn es gesendet wird, ersetzt es das Fragment. Dies bedeutet, dass die Liste jedes Mal erneuert wird. Halten Sie daher die Liste der Elemente nicht im Speicher.
Wesley Franks

44

// In Fragment_1.java

Bundle bundle = new Bundle();
bundle.putString("key","abc"); // Put anything what you want

Fragment_2 fragment2 = new Fragment_2();
fragment2.setArguments(bundle);

getFragmentManager()
      .beginTransaction()
      .replace(R.id.content, fragment2)
      .commit();

// In Fragment_2.java

Bundle bundle = this.getArguments();

if(bundle != null){
     // handle your code here.
}

Hoffe das hilft dir.


1
Saubere Antwort, um den Hauptpunkt zu zeigen. mit putString(oder putInt) ist die Antwort!
Mehdi Dehghani

22

Von der Entwickler- Website:

Oft möchten Sie, dass ein Fragment mit einem anderen kommuniziert, um beispielsweise den Inhalt basierend auf einem Benutzerereignis zu ändern. Die gesamte Kommunikation von Fragment zu Fragment erfolgt über die zugehörige Aktivität. Zwei Fragmente sollten niemals direkt kommunizieren.

Sie können mithilfe der Aktivität zwischen Fragmenten kommunizieren. Mit diesem Ansatz können Sie zwischen Aktivitäten und Fragmenten kommunizieren .

Bitte überprüfen Sie auch diesen Link.


Der zweite Link, den Sie angegeben haben, zeigt, wie zwischen Fragmenten kommuniziert wird, wenn sie sich in derselben Aktivität befinden. Wie kommuniziere ich, wenn beide unterschiedliche Aktivitäten ausführen?
Vamsi Challa

5

Zunächst sind alle Antworten richtig. Sie können die Daten mit Ausnahme von benutzerdefinierten Objekten mithilfe von übergeben Intent. Wenn Sie die benutzerdefinierten Objekte übergeben möchten, müssen Sie Serialazableoder Parcelablean Ihre benutzerdefinierte Objektklasse implementieren . Ich fand es zu kompliziert ...

Wenn Ihr Projekt einfach ist, versuchen Sie es zu verwenden DataCache. Das bietet eine super einfache Möglichkeit, Daten zu übergeben. Ref: Github-Projekt CachePot

1- Stellen Sie dies auf Ansicht oder Aktivität oder Fragment ein, um Daten zu senden

DataCache.getInstance().push(obj);

2- Holen Sie sich Daten wie unten beschrieben

public class MainFragment extends Fragment
{
    private YourObject obj;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        obj = DataCache.getInstance().pop(YourObject.class);

    }//end onCreate()
}//end class MainFragment

Wäre es nicht einfacher, eine zusätzliche Klasse mit darin enthaltenen statischen Werten zu verwenden? Auf diese Werte kann dann von beiden Fragmenten zugegriffen werden, sodass keine zusätzliche Bibliothek zum Zwischenspeichern benutzerdefinierter Objekte erforderlich ist.
Neph

4

Die neueste Lösung zum Übergeben von Daten zwischen Fragmenten kann mithilfe von Android-Architekturkomponenten wie ViewModel und LiveData implementiert werden. Mit dieser Lösung müssen Sie keine Schnittstelle für die Kommunikation definieren und können die Vorteile der Verwendung von Ansichtsmodellen wie dem Überleben von Daten aufgrund von Konfigurationsänderungen nutzen.

In dieser Lösung teilen sich die an der Kommunikation beteiligten Fragmente dasselbe Ansichtsmodellobjekt, das an ihren Aktivitätslebenszyklus gebunden ist. Das Ansichtsmodellobjekt enthält ein Livedata-Objekt. Ein Fragment legt Daten fest, die an das Livedata-Objekt übergeben werden sollen, und der zweite Fragmentbeobachter ändert die Livedata-Daten und empfängt die Daten.

Hier ist das vollständige Beispiel http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel


3

Argumente zwischen Fragmenten übergeben. Dies ist ziemlich spät, um diese Frage zu beantworten, aber es könnte jemandem helfen! Fragment_1.java

Bundle i = new Bundle(); 
            i.putString("name", "Emmanuel");

            Fragment_1 frag = new Fragment_1();
            frag.setArguments(i);
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame
                            , new Fragment_2())
                    .commit();

Dann können Fragment_2.javaSie in Ihrem die Parameter normalerweise innerhalb Ihres onActivityCreated z

 Intent intent = getActivity().getIntent();
    if (intent.getExtras() != null) {
        String name =intent.getStringExtra("name");
    }

3

Ich denke, ein guter Weg, um dieses Problem zu lösen, ist die Verwendung einer benutzerdefinierten Oberfläche.

Nehmen wir an, Sie haben zwei Fragmente (A und B), die sich innerhalb derselben Aktivität befinden, und Sie möchten Daten von A nach B senden.

Schnittstelle:

public interface OnDataSentListener{
    void onDataSent(Object data);
}

Aktivität:

    public class MyActivity extends AppCompatActivity{

            private OnDataSentListener onDataSentListener;

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

                FragmentTransaction trans = getFragmentManager().beginTransaction();

                FragmentA fa = new FragmentA();
                FragmentB fb = new FragmentB();

               fa.setOnDataSentListener(new Listeners.OnDataSentListener() {
                    @Override
                    public void onDataSent(Object data) {
                         if(onDataSentListener != null)  onDataSentListener.onDataSent(data);
                    }
               });

                transaction.add(R.id.frame_a, fa);
                transaction.add(R.id.frame_b, fb);

                transaction.commit();
            }

            public void setOnDataSentListener(OnDataSentListener listener){
                this.onDataSentListener = listener;
            }
        }

Fragment A:

public class FragmentA extends Fragment{

    private OnDataSentListener onDataSentListener;

    private void sendDataToFragmentB(Object data){
        if(onDataSentListener != null) onDataSentListener.onDataSent(data);
    }

    public void setOnDataSentListener(OnDataSentListener listener){
        this.onDataSentListener = listener;
    }
}

Fragment B:

public class FragmentB extends Fragment{

    private void initReceiver(){
        ((MyActivity) getActivity()).setOnDataSentListener(new OnDataSentListener() {
            @Override
            public void onDataSent(Object data) {
                //Here you receive the data from fragment A
            }
        });
    }
}

2

Die Kommunikation zwischen Fragmenten ist ziemlich kompliziert (ich finde das Listener-Konzept etwas schwierig zu implementieren).

Es ist üblich, einen 'Event Bus' zu verwenden, um diese Kommunikationen zu abstrahieren. Dies ist eine Bibliothek eines Drittanbieters, die diese Kommunikation für Sie erledigt.

'Otto' wird häufig verwendet, um dies zu tun, und es könnte sich lohnen, einen Blick darauf zu werfen : http://square.github.io/otto/


2

Übergeben von Daten vom Fragment an ein anderes Fragment

  • Vom ersten Fragment

    // Set data to pass
    MyFragment fragment = new MyFragment(); //Your Fragment
    Bundle bundle = new Bundle();
    bundle.putInt("year", 2017)  // Key, value
    fragment.setArguments(bundle); 
    // Pass data to other Fragment
    getFragmentManager()
     .beginTransaction()
     .replace(R.id.content, fragment)
     .commit(); 
  • Auf dem zweiten Fragment

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
    
         Bundle bundle = this.getArguments();
         if (bundle != null) {
             Int receivedYear = bundle.getInt("year", ""); // Key, default value
         } 
    }

1

Diese einfache Implementierung hilft dabei, Daten auf einfache Weise zwischen Fragmenten zu übertragen. Denken Sie, Sie möchten Daten von 'Frgement1' an 'Fragment2' übergeben.

In Fragment1 (Zu sendende Daten festlegen)

 Bundle bundle = new Bundle();
 bundle.putString("key","Jhon Doe"); // set your parameteres

 Fragment2 nextFragment = new Fragment2();
 nextFragment.setArguments(bundle);

 FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
 fragmentManager.beginTransaction().replace(R.id.content_drawer, nextFragment).commit();

In Fragment2 onCreateView-Methode (Get-Parameter)

String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost

In meiner App versuche ich, dies zum Laufen zu bringen, aber obwohl der Wert übergeben wird, wird er auf fragment2 nicht angezeigt. Ich glaube, ich mache einen Fehler beim Festlegen von R.id.content_drawer. Kann mich jemand anleiten, was die richtige Kennung für R.id.content_drawer mit einem .xml-Beispiel sein könnte?
Falke

1

Kotlin Weg

Verwenden Sie einen SharedViewModelVorschlag in der offiziellen ViewModel- Dokumentation

Es ist sehr häufig, dass zwei oder mehr Fragmente in einer Aktivität miteinander kommunizieren müssen. Stellen Sie sich einen häufigen Fall von Master-Detail-Fragmenten vor, bei dem Sie ein Fragment haben, in dem der Benutzer ein Element aus einer Liste auswählt, und ein anderes Fragment, das den Inhalt des ausgewählten Elements anzeigt. Dieser Fall ist niemals trivial, da beide Fragmente eine Schnittstellenbeschreibung definieren müssen und die Eigentümeraktivität die beiden miteinander verbinden muss. Außerdem müssen beide Fragmente das Szenario behandeln, in dem das andere Fragment noch nicht erstellt oder sichtbar ist.

Dieser häufige Schmerzpunkt kann mithilfe von ViewModel-Objekten behoben werden. Diese Fragmente können ein ViewModel mithilfe ihres Aktivitätsbereichs für diese Kommunikation freigeben

Implementieren Sie zuerst fragment-ktx , um Ihr Ansichtsmodell einfacher zu instanziieren

dependencies {
    implementation "androidx.fragment:fragment-ktx:1.2.2"
} 

Dann müssen Sie nur noch die Daten in das Ansichtsmodell einfügen, die Sie mit dem anderen Fragment teilen möchten

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

Zum Abschluss instanziieren Sie einfach Ihr viewModel in jedem Fragment und legen den Wert von fest selected aus dem Fragment fest, für das Sie die Daten festlegen möchten

Fragment A.

class MasterFragment : Fragment() {

    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
        model.select(item)
      }

    }
}

Warten Sie dann einfach an Ihrem Fragment-Ziel auf diesen Wert

Fragment B.

 class DetailFragment : Fragment() {

        private val model: SharedViewModel by activityViewModels()

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
                // Update the UI
            })
        }
    }

Sie können es auch umgekehrt machen


0

100% funktionierende Lösung: (Wenn Sie Hilfe haben, vergessen Sie nicht, die positive Bewertung abzugeben.)

Fügen Sie in Ihr erstes Fragment diesen Code ein:

    editprofile.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Fragment_editprofile Fragment = new Fragment_editprofile();
.
.
.
.
.


                Fragment.getintentdetails(tv_name.getText().toString(),
                            tv_mob.getText().toString(), tv_email.getText().toString(), tv_dob.getText().toString(),
                            tv_gender.getText().toString(), photointent);

                }
            });

Machen Sie im zweiten Fragment die folgende Methode:

public void getintentdetails(String name, String mobile, String email, String dob, String gender,
                                 String photointent) {

        this.name_str= name;
        this.mob_str= mobile;
        this.email_str= email;
        this.dob_str= dob;
        this.gender_str= gender;
        this.photo_str= photointent;

    }

Definieren Sie dann eine Variable auf Klassenebene:

String name_str, mob_str, dob_str, photo_str, email_str, gender_str;

Machen Sie dann eine andere Methode im zweiten Fragment, um den Wert festzulegen:

  setexistingdetails();


private void setexistingdetails() {

        if(!name_str.equalsIgnoreCase(""))
            (et_name).setText(name_str);
        if(!mob_str.equalsIgnoreCase(""))
            et_mobile.setText(mob_str);
        if(!email_str.equalsIgnoreCase(""))
            email_et.setText(email_str);
        if(!dob_str.equalsIgnoreCase(""))
            dob_et.setText(dob_str);
        if(!gender_str.equalsIgnoreCase("")){
            if (gender_str.equalsIgnoreCase("m")){
                male_radio.setChecked(true);
            }else {
                female_radio.setChecked(true);
            }
        }
        if(!photo_str.equalsIgnoreCase("")){
            try {
                Picasso.get().load(Const.BASE_PATH+"include/sub-domain/GENIUS/"+photo_str).into(adminpropic_edit);
            } catch (Exception e) {            }
        }
    }

0

Sie können Ihr Ziel mit ViewModel und Live Data erreichen, die von Arnav Rao gelöscht wurden . Jetzt habe ich ein Beispiel gegeben, um es sauberer zu machen.

Zunächst wird die Annahme ViewModelbenannt SharedViewModel.java.

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }
    public LiveData<Item> getSelected() {
        return selected;
    }
}

Dann ist das Quellfragment das, MasterFragment.javavon dem aus wir Daten senden möchten.

public class MasterFragment extends Fragment {
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {

            // Data is sent

            model.select(item);
        });
    }
}

Und schließlich ist das Zielfragment der Ort, DetailFragment.javaan dem wir die Daten empfangen möchten.

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), { item ->

           // Data is received 

        });
    }
}

0

OK, nachdem ich so viel hier gegraben habe, habe ich eine einfache Lösung gefunden. Eigentlich sollten Sie die Daten niemals von Fragment zu Fragment weitergeben. Es ist immer eine schlechte Idee. Sie können Daten von Fragment A an Aktivität übergeben und die Daten von Aktivität in Fragment B abrufen.

For Example
//fragment A
//your method that will be called in Main Activity for getting data from this fragment
public List<customDataModel> getlist(){
return mlist; //your custom list 
}
buttonopen.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //before calling  your new fragment, send a Broadcast signal to your main activity
 mContext.sendBroadcast(new Intent("call.myfragment.action"));
//here you are now changing the fragment
Fragment fragment1 = new VolunteerListDetailsFragment();

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.content_frame, fragment1);
            ft.commit();
        }
    });

// in der Hauptaktivität

this.registerReceiver(mBroadcastReceiver, new IntentFilter("call.myfragment.action"));//this line should be in your onCreate method
   BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
//init the fragment A
FragmenA fragment =
                (FragmentA) getSupportFragmentManager().findFragmentById(R.id.content_frame);
        mlistdetails = fragment.getlist();//this is my method in fragmentA which is retuning me a custom list, init this list type in top of on create fragment


    }
};
//here you are creating method that is returning the list that you just recieved From fragmentA
public List<customDataModel> getcustomlist(){
return mlistdetails; //you are returning the same list that you recived from fragmentA
}

// jetzt in FragmentB

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

    View rootView = (View) inflater.inflate(R.layout.vol_listdetails, container, false);

    mlistdetails=((MainActivity)getActivity()).getcustomlist();//here you are calling the method that you have created in Main Activity

    Toast.makeText(getActivity().getApplicationContext(), mlistdetails.get(0).getItemqty(), Toast.LENGTH_SHORT).show();
    return rootView;

}

-2

Ich habe Anfängern wie mir etwas wirklich Leichtes gemacht. Ich habe eine Textansicht in meiner activity_main.xml erstellt und eingefügt

id=index
visibility=invisible

dann bekomme ich diese textansicht aus dem ersten fragment

index= (Textview) getActivity().findviewbyid(R.id.index)
index.setText("fill me with the value")

und dann im zweiten Fragment bekomme ich den Wert

index= (Textview) getActivity().findviewbyid(R.id.index)
String get_the_value= index.getText().toString();

ich hoffe es hilft!


Die Antwort bezieht sich nicht auf die gestellte Frage
Kanagalingam
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.