Übergeben eines Objekts von einer Aktivität an ein Fragment

76

Ich habe eine, Activitydie eine verwendet Fragment. Ich möchte einfach ein Objekt von diesem Activityan das übergeben Fragment.

Wie könnte ich das machen? In allen Tutorials, die ich bisher gesehen habe, wurden Daten aus Ressourcen abgerufen.

EDIT:

Lassen Sie uns etwas genauer sein:

Meine Aktivität hat einen ListViewauf der linken Seite. Wenn Sie darauf klicken, ist die Idee, ein Fragmentauf den rechten Teil zu laden .

Wenn ich dies Activityeingebe, wird ein Objekt Categorydurch das gegeben Intent. Dieses Objekt enthält eine Liste anderer Objekte Questions(die eine Liste von Zeichenfolgen enthält). Diese QuestionsObjekte werden in der ListView angezeigt. Wenn ich auf ein Element aus dem klicke ListView, möchte ich die Liste von Stringin Fragment(in a ListView) anzeigen .

Dazu rufe ich das setContentView()von meinem Activitymit einem Layout auf. In diesem Layout ist die Fragmentmit der richtigen Klasse aufzurufende Klasse definiert . Wenn ich dies aufrufe setContentView(), wird das onCreateView()von my Fragmentaufgerufen, aber zu diesem Zeitpunkt gibt das getArguments()null zurück.

Wie könnte ich es schaffen, es vor dem Anruf von füllen zu lassen onCreateView()? (Sag mir, wenn ich nicht klar genug bin)

Vielen Dank

Nico
quelle

Antworten:

132

Erstellen Sie eine statische Methode in der Fragmentund rufen Sie sie dann mit ab getArguments().

Beispiel:

public class CommentsFragment extends Fragment {
  private static final String DESCRIBABLE_KEY = "describable_key";
  private Describable mDescribable;

  public static CommentsFragment newInstance(Describable describable) {
    CommentsFragment fragment = new CommentsFragment();
    Bundle bundle = new Bundle();
    bundle.putSerializable(DESCRIBABLE_KEY, describable);
    fragment.setArguments(bundle);

    return fragment;
  }

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

    mDescribable = (Describable) getArguments().getSerializable(
        DESCRIBABLE_KEY);

    // The rest of your code
}

Sie können es später so nennen Activity:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = CommentsFragment.newInstance(mDescribable);
ft.replace(R.id.comments_fragment, fragment);
ft.commit();
Macarse
quelle
8
Was ist es, wenn ich ein Objekt übergeben möchte, das nicht serialisierbar ist?
Bagusflyer
1
putParcelable ist der beste Weg
Panchicore
9
Ich würde gerne wissen, warum nicht einfach fragment.mDescribable = describable;in newInstance gesetzt? Es funktioniert, aber fehlt mir hier etwas?
Rahul Thakur
2
@RahulThakur Hier fehlt der Punkt des mPräfixes. Da die Java-Community das Konzept der Datenkapselung nachdrücklich befürwortet, sollte beachtet werden, dass private Felder nicht außerhalb zugänglich sein müssen. Der Grund dafür, dass es als Parameter von der Singleton-Methode übergeben wird, liegt darin, dass dieses Feld in diesem Kontext obligatorisch ist und somit das potenzielle Risiko verringert, dass Sie vergessen haben, seinen Wert zuzuweisen.
Mr5 5.
16
Beste Antwort, aber Sie vergessen zu sagen, Objectdass Geräte Serializablefunktionieren müssen (im Fall das Objekt Describable).
Gabriel Stafoca
12

Sie sollten in Ihrem Fragment eine Methode erstellen, die den Objekttyp akzeptiert, den Sie übergeben möchten. In diesem Fall habe ich es "setObject" genannt (kreativ huh? :)) Diese Methode kann dann jede Aktion ausführen, die Sie mit diesem Objekt benötigen.

MyFragment fragment;

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

        if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
            fragment = new MyFragment();
            getSupportFragmentManager().beginTransaction().add(android.R.id.content, detailsFragment)
                    .commit();
        } else {
           fragment = (MyFragment) getSupportFragmentManager().findFragmentById(
                    android.R.id.content);
        }


        fragment.setObject(yourObject); //create a method like this in your class "MyFragment"
}

Beachten Sie, dass ich die Support-Bibliothek verwende und Aufrufe von getSupportFragmentManager () nur getFragmentManager () für Sie sind, je nachdem, mit was Sie arbeiten

dymmeh
quelle
2
Seien Sie vorsichtig, wenn Sie diese Methode für ein Fragment verwenden, das Ihre Hosting-Ansicht überleben kann (keepInstance true).
Jannie Theunissen
7
Das wird nicht funktionieren. Wenn Ihre App im Hintergrund stirbt und der Benutzer sie wieder in den Vordergrund setObjectrückt , wird sie nicht unbedingt aufgerufen.
Martin Konecny
5
@MartinKonecny ​​In diesem Fall wird die onCreate-Methode erneut aufgerufen (da die Aktivität neu erstellt wird) und daher auch setObject aufgerufen. Ist dies nicht der Fall, erläutern Sie bitte Ihren Kommentar. Vielen Dank.
fklappan
Dies funktioniert bei View-Pager-Fragmenten nicht. da das Objekt beim Übergang nicht erhalten bleibt.
Rafa
12

In Ihrer Aktivitätsklasse:

public class BasicActivity extends Activity {

private ComplexObject co;

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

    co=new ComplexObject();
    getIntent().putExtra("complexObject", co);

    FragmentManager fragmentManager = getFragmentManager();
    Fragment1 f1 = new Fragment1();
    fragmentManager.beginTransaction()
            .replace(R.id.frameLayout, f1).commit();

}

Hinweis: Ihr Objekt sollte eine serialisierbare Schnittstelle implementieren

Dann in Ihrem Fragment:

public class Fragment1 extends Fragment {

ComplexObject co;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Intent i = getActivity().getIntent();

    co = (ComplexObject) i.getSerializableExtra("complexObject");

    View view = inflater.inflate(R.layout.test_page, container, false);
    TextView textView = (TextView) view.findViewById(R.id.DENEME);
    textView.setText(co.getName());

    return view;
}
}
Tugce Saritas
quelle
4

Das Übergeben von Argumenten per Bundle ist auf einige Datentypen beschränkt. Sie können jedoch alle Daten folgendermaßen auf Ihr Fragment übertragen:

Erstellen Sie in Ihrem Fragment eine öffentliche Methode wie diese

public void passData(Context context, List<LexItem> list, int pos) {
    mContext = context;
    mLexItemList = list;
    mIndex = pos;
}

Rufen Sie in Ihrer Aktivität passData () mit allen erforderlichen Datentypen auf, nachdem Sie das Fragment instanziiert haben

        WebViewFragment myFragment = new WebViewFragment();
        myFragment.passData(getApplicationContext(), mLexItemList, index);
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.my_fragment_container, myFragment);
        ft.addToBackStack(null);
        ft.commit();

Anmerkung: Mein Fragment erweitert "android.support.v4.app.Fragment", daher muss ich "getSupportFragmentManager ()" verwenden. Natürlich funktioniert dieses Prinzip auch mit einer Fragmentklasse, die "Fragment" erweitert, aber dann müssen Sie "getFragmentManager ()" verwenden.

thpitsch
quelle
4

Referenz aus dem folgenden Beispiel abrufen.

1. Im Fragment : Erstellen Sie eine Referenzvariable für die Klasse, deren Objekt Sie im Fragment haben möchten. Erstellen Sie einfach eine Setter-Methode für die Referenzvariable und rufen Sie den Setter auf, bevor Sie das Fragment aus der Aktivität ersetzen.

 MyEmployee myEmp;
 public void setEmployee(MyEmployee myEmp)
 {
     this.myEmp = myEmp;
 }

2. In Aktivität :

   //we need to pass object myEmp to fragment myFragment

    MyEmployee myEmp = new MyEmployee();

    MyFragment myFragment = new MyFragment();

    myFragment.setEmployee(myEmp);

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.main_layout, myFragment);
    ft.commit();
Shivam Agarwal
quelle
1

Gehen Sie wie folgt vor, um ein Objekt an ein Fragment zu übergeben:

Speichern Sie zuerst die Objekte in Bundle. Vergessen Sie nicht, implementierbare Geräte in die Klasse aufzunehmen.

            CategoryRowFragment fragment = new CategoryRowFragment();

            // pass arguments to fragment
            Bundle bundle = new Bundle();

            // event list we want to populate
            bundle.putSerializable("eventsList", eventsList);

            // the description of the row
            bundle.putSerializable("categoryRow", categoryRow);

            fragment.setArguments(bundle);

Rufen Sie dann die Bundles in Fragment ab

       // events that will be populated in this row
        mEventsList = (ArrayList<Event>)getArguments().getSerializable("eventsList");

        // description of events to be populated in this row
        mCategoryRow = (CategoryRow)getArguments().getSerializable("categoryRow");

Dave o Grady
quelle
0

Wenn die Daten während des gesamten Anwendungslebenszyklus überleben und von mehreren Fragmenten oder Aktivitäten gemeinsam genutzt werden sollen, wird Modelmöglicherweise eine Klasse in Betracht gezogen, die weniger Serialisierungsaufwand hat.

Überprüfen Sie dieses Entwurfsbeispiel

Xerusial
quelle
0

Dieser hat für mich gearbeitet:

In Aktivität:

User user;
public User getUser(){ return this.user;}

In der onCreateView-Methode von Fragment:

User user = ((MainActivity)getActivity()).getUser(); 

Ersetzen Sie das MainActivitydurch Ihren Aktivitätsnamen.

Pranjal Choladhara
quelle