Jak przekazać zmienną z Activity do Fragment i przekazać ją z powrotem?


135

Obecnie tworzę aplikację na Androida i chcę przekazać datę między działaniem a fragmentem. Moja aktywność posiada przycisk, który otwiera fragment: DatePickerFragment.

W swojej działalności pokazuję datę, którą chcę zmodyfikować fragmentem. Chcę więc przekazać datę selektorowi daty i odesłać ją do ćwiczenia.

Wypróbowałem wiele rozwiązań, ale żadne nie działa. Prostym sposobem byłoby przekazanie argumentu, ale nie można tego zrobić z fragmentami.


Mój problem jest dokładnie taki sam jak twój. Zastanawiam się, dlaczego przykłady traktują tylko same fragmenty jako „użytkowników” selektora dat, a nie aktywność, która je uruchomiła.
— Claudio,

Odpowiedzi:


213

Aby przekazać informacje do fragmentu , należy ustawić Argumenty podczas jego tworzenia i można później pobrać ten argument metodą onCreate lub onCreateView swojego fragmentu.

W funkcji newInstance twojego fragmentu dodajesz argumenty, które chcesz do niego wysłać:

/**
 * Create a new instance of DetailsFragment, initialized to
 * show the text at 'index'.
 */
public static DetailsFragment newInstance(int index) {
    DetailsFragment f = new DetailsFragment();
    // Supply index input as an argument.
    Bundle args = new Bundle();
    args.putInt("index", index);
    f.setArguments(args);
    return f;
}

Następnie wewnątrz fragmentu metody onCreatelub onCreateViewmożesz pobrać argumenty w ten sposób:

Bundle args = getArguments();
int index = args.getInt("index", 0);

Jeśli chcesz teraz komunikować się ze swoim fragmentem ze swoją aktywnością (wysyłając lub nie dane) , musisz użyć interfejsów. Sposób, w jaki możesz to zrobić, jest naprawdę dobrze wyjaśniony w samouczku dokumentacji komunikacji między fragmentami. Ponieważ wszystkie fragmenty komunikują się między sobą za pośrednictwem działania, w tym samouczku możesz zobaczyć, jak możesz wysłać dane z rzeczywistego fragmentu do jego kontenera działania, aby użyć tych danych w działaniu lub wysłać je do innego fragmentu, który zawiera działanie.

Samouczek dokumentacji:

http://developer.android.com/training/basics/fragments/communicating.html


10
Myślę, że celem ludzi, którzy ciągle zadają to pytanie, jest to, że nie jest to dobrze wyjaśnione w dokumentacji.
— Michael Alan Huff,

1
Nadal nie wiem, która metoda jest najlepsza w użyciu, twoja lub ta poniżej, na którą odpowiedział @Elenasys
— Yoann Hercouet

Istnieje nowy sposób udostępniania danych między fragmentami przy użyciu komponentów architektury (I / O '17): developer.android.com/topic/libraries/architecture/ ...
— jpardogo

A co z tymi fragmentami, które są tworzone w układzie XML?
— ralphgabb

Nie chcę już używać metody statycznej.
— Ahamadullah Saikat

89

Wysyłanie danych z ActivitydoFragment

Czynność:

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:

Odczytywanie wartości we fragmencie

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

Ale jeśli chcesz wysłać wartości z fragmentu do działania, przeczytaj odpowiedź jpardogo, potrzebujesz interfejsów, więcej informacji: Komunikacja z innymi fragmentami


2
Jak przekazać obiekt niestandardowy? Użyłem, Parcelableale to dało miclass cast exception
— viper

to rozwiązanie nie działa dla mnie, nie mogę znaleźć skąd zaimportować transakcję
— thebeancounter

Cóż, jeśli załadujesz Fragment do swojej Aktywności, możesz wysłać wartości za pośrednictwem pakietu zdefiniowanego w Twojej transakcji. Wyjaśnij, jaki jest twój scenariusz?
— Jorgesys

8

dzięki @ ρяσѕρєя K i Terry ... bardzo mi to pomaga i działa doskonale

Z Aktywności wysyłasz dane z zamiarem:

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

oraz w metodzie Fragment onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // get arguments
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}

odniesienie: Wyślij dane z aktywności do fragmentu w systemie Android


7

Użyj biblioteki EventBus, aby przekazać zdarzenie, które może zawierać zmienną, w tę iz powrotem. To dobre rozwiązanie, ponieważ pozwala na luźne powiązanie twoich działań i fragmentów

https://github.com/greenrobot/EventBus


4
Nie mogę powiedzieć, że to nie jest dobre rozwiązanie, ale słowo ostrzeżenia jest na miejscu. Chociaż EventBus jest niezwykle łatwy w użyciu, tutaj również tkwi jego niebezpieczeństwo. Jeśli zaczniesz dodawać zbyt wiele sygnałów, luźno powiązany charakter może naprawdę utrudnić śledzenie, kto dzwoni do kogo i gdzie mają miejsce różne wydarzenia.
— Johan Paul,

2

Dla wszystkich programistów Kotlin:

Oto proponowane rozwiązanie Android Studio do wysyłania danych do Twojego fragmentu (= podczas tworzenia pustego fragmentu za pomocą polecenia Plik -> Nowy -> Fragment -> Fragment (pusty) i zaznaczania opcji „dołącz metody fabryki fragmentów”).

Umieść to w swoim fragmencie:

class MyFragment: Fragment {

...

    companion object {

            @JvmStatic
            fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
                arguments = Bundle().apply {
                    putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
                }
            }
     }
}

.applyto fajna sztuczka do ustawiania danych podczas tworzenia obiektu, lub jak to tutaj stwierdzają :

Wywołuje określoną funkcję [blok] z thiswartością jako odbiorcą i zwraca thiswartość.

Następnie w swojej aktywności lub fragmencie wykonaj:

val fragment = MyFragment.newInstance(false)
... // transaction stuff happening here

i przeczytaj Argumenty w swoim fragmencie, takie jak:

private var isMyBoolean = false

override fun onAttach(context: Context?) {
    super.onAttach(context)
    arguments?.getBoolean("REPLACE WITH A STRING CONSTANT")?.let {
        isMyBoolean = it
    }
}

Aby „wysłać” dane z powrotem do swojego działania , po prostu zdefiniuj funkcję w swoim działaniu i wykonaj następujące czynności w swoim fragmencie:

(activity as? YourActivityClass)?.callYourFunctionLikeThis(date) // your function will not be called if your Activity is null or is a different Class

Ciesz się magią Kotlina!


1

Wysyłanie danych z działania do fragmentów połączonych przez XML

Jeśli utworzysz fragment w Android Studio za pomocą jednego z szablonów, np. Plik> Nowy> Fragment> Fragment (Lista), to fragment ten jest linkowany przez XML. Metoda newInstance jest tworzona we fragmencie, ale nigdy nie jest wywoływana, więc nie można jej używać do przekazywania argumentów.

Zamiast tego w Activity zastąp metodę onAttachFragment

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof DetailsFragment) {
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);        
     }
}

Następnie przeczytaj argumenty we fragmencie metody onCreate zgodnie z innymi odpowiedziami


0

Możesz po prostu utworzyć instancję fragmentu za pomocą pakietu:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.