Wysyłaj dane z aktywności do fragmentu w Androidzie

316

Mam dwie klasy. Pierwsza to aktywność, druga to fragment, w którym mam trochę EditText. W działaniu mam podklasę z zadaniem asynchronicznym, aw metodzie doInBackgrounduzyskuję wynik, który zapisuję do zmiennej. Jak mogę wysłać tę zmienną z podklasy „moja aktywność” do tego fragmentu?

użytkownik1302569
źródło

Odpowiedzi:

662

Z działania 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) {
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}
ρяσсρєя K
źródło
15
czy możesz przekazać obiekt do fragmentu?
yeahman,
63
Hmm dostaję NullPointerException podczas dzwonieniagetArguments().getString(key)
Nima G
9
NullPointerException "String strtext setArguments (). GetString (" edttext ");"
Jorgesys
4
Podczas czytania zawartości pakietu we fragmencie zawsze najpierw otrzymaj pakiet do obiektu pakietu za pomocą metody getArguments i sprawdź, czy nie ma wartości null. W przeciwnym razie metoda getString zostanie zastosowana na wartości null, a więc NPE, gdy żaden pakiet nie zostanie przekazany. Pozwoli to uniknąć wyjątków wskaźnika zerowego, gdy pakiet nie zostanie przekazany.
balachandarkm
3
@Aznix. Nie zaleca się tworzenia konstruktora dla fragmentu.
Azam,
108

Możesz również uzyskać dostęp do danych o aktywności z fragmentu:

Czynność:

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
źródło
78
To rozwiązanie integruje ścisłe powiązanie między Twoją aktywnością a Fragmentem, lepiej wykorzystać Bundleklasę do przekazywania informacji. Alternatywnie możesz sprawić, aby ta getMyData()metoda została odziedziczona i zaimplementowana z interfejsu i Fragmentsprawdź, czy getActivity zwraca instanceofinterfejs onAttach().
Rudi Kershaw
1
To najlepsze rozwiązanie dla mnie. Również jeśli myString jest publiczny, nie zadeklarowałeś metody getMyData ()
Burak Öztürk
1
Bieżąca zaakceptowana odpowiedź zwraca wyjątek wskaźnika zerowego. To powinna być zaakceptowana odpowiedź
Richmond,
9
To nie powinna być zaakceptowana odpowiedź. Ciasnego połączenia można łatwo uniknąć. Jest to generalnie zły pomysł i sprawia, że ​​fragment jest bezużyteczny, może równie dobrze nie mieć fragmentu, jeśli zamierzasz go użyć tylko w połączeniu z działaniem. Fragmentu nie można ponownie wykorzystać w innych działaniach.
Martin Marconcini,
51

Znalazłem wiele odpowiedzi tutaj @ stackoverflow.com, ale zdecydowanie jest to poprawna odpowiedź:

„Wysyłanie danych z aktywności do fragmentu w Androidzie”.

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) {
        Bundle bundle = this.getArguments();
        String myValue = bundle.getString("message");
        ...
        ...
        ...
        }

Lub tylko

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        String myValue = this.getArguments().getString("message");
        ...
        ...
        ...
        }
Jorgesys
źródło
Myślę, że nie jest to najlepsze podejście do aktualizowania wyników wyszukiwania onQueryTextSubmit w ListView, który jest zagnieżdżony we fragmencie (jeśli somybody pisze szybko, wysyła argumenty dwa razy na sekundę)?
Martin Pfeffer,
1
A co z Object insted string lub int?
Dario
2
@Jorgesys Co z tym rozwiązaniem? developer.android.com/training/basics/fragments/…
yozhik
23

Ta odpowiedź może być za późno. ale przyda się przyszłym czytelnikom.

Mam kilka kryteriów. Zakodowałem wybranie pliku z zamiarem. i wybrany plik do przekazania do określonego fragmentu w celu dalszego przetwarzania. Mam wiele fragmentów o funkcjonalności pobierania plików. w tym momencie za każdym razem sprawdzanie warunku i pobranie fragmentu i przekazanie wartości jest dość obrzydliwe. więc postanowiłem przekazać wartość za pomocą interfejsu.

Krok 1: Utwórz interfejs dla głównej aktywności.

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

Krok 2: Utwórz odwołanie SelectedBundle dla tego samego działania

   SelectedBundle selectedBundle;

Krok 3: utwórz metodę w tym samym działaniu

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

Krok 4: Konieczne jest zainicjowanie odwołania SelectedBundle, z których wszystkie są fragmentami, wymaga funkcji pobierania plików. Umieszczasz ten kod na onCreateView(..)metodzie fragmentu

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

Krok 5: moim przypadku muszę przekazać obraz Uri z HomeActivity do fragmentu. Użyłem tej funkcji w metodzie onActivityResult.

onActivityResult z MainActivity, przekaż wartości do fragmentów za pomocą interfejsu.

Uwaga: Twoja sprawa może być inna. możesz zadzwonić z dowolnego miejsca w HomeActivity.

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

To wszystko. Zaimplementuj każdy potrzebny fragment w FragmentClass. Jesteś wspaniały. uczyniłeś. ŁAŁ...

Noorul
źródło
15

Podstawową ideą korzystania z Fragmentów (F) jest tworzenie samowystarczalnych komponentów interfejsu użytkownika wielokrotnego użytku w aplikacjach na Androida. Fragmenty te są zawarte w działaniach i istnieje powszechny (najlepszy) sposób tworzenia ścieżek komunikacji od A -> F i FA. Konieczne jest komunikowanie się między FF poprzez działanie, ponieważ wtedy tylko fragmenty zostają oddzielone i samowystarczalne.

Tak więc przekazywanie danych z A -> F będzie takie samo, jak wyjaśnione przez ρяσсρєя K. Oprócz tej odpowiedzi, Po utworzeniu Fragmentów wewnątrz Działania, możemy również przekazać dane do metod wywoływania fragmentów w Fragmentach.

Na przykład:

    ArticleFragment articleFrag = (ArticleFragment)
                    getSupportFragmentManager().findFragmentById(R.id.article_fragment);
    articleFrag.updateArticleView(position);
diyoda_
źródło
15

Najlepszym i najwygodniejszym podejściem jest wywoływanie instancji fragmentu i wysyłanie danych w tym czasie. każdy fragment domyślnie ma metodę instancji

Na przykład: jeśli twój fragment ma nazwę MyFragment

więc wywołasz swój fragment z takiej aktywności:

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

* R.id.container jest identyfikatorem mojego FrameLayout

więc w MyFragment.newInstance („data1”, „data2”) możesz wysyłać dane do fragmentu, aw swoim fragmencie otrzymujesz te dane w 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;
    }

a następnie w metodzie fragmentu onCreate otrzymasz dane:

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

więc teraz mParam1 ma dane1, a mParam2 ma dane2

teraz możesz używać tego mParam1 i mParam2 w swoim fragmencie.

Pre_hacker
źródło
czym jest tutaj kontener R.id.? czy miałeś na myśli R.id.container_current to jest wartość int.
shaurya uppal
@s * R.id.container jest identyfikatorem mojego FrameLayout
Pre_hacker
Jak dotąd najlepsze wyjaśnienie, jakie kiedykolwiek znalazłem, aby przekazać dane dotyczące dodawania / zastępowania fragmentu za pomocą Menedżera fragmentów. Działa jak klejnot! Dzięki!
sam
używane R.id.nav_host_fragment zamiast R.id.container
Bahaa Hany
10

Chciałbym dodać dla początkujących, że różnica między 2 najbardziej uprzywilejowanymi odpowiedziami tutaj wynika z różnych zastosowań fragmentu.

Jeśli korzystasz z fragmentu w klasie java, w którym masz dane, które chcesz przekazać, możesz zastosować pierwszą odpowiedź, aby przekazać dane:

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

Jeśli jednak użyjesz na przykład domyślnego kodu podanego przez Android Studio dla fragmentów z kartami, ten kod nie będzie działać.

Nie będzie działać, nawet jeśli zastąpisz domyślny PlaceholderFragment swoimi FragmentClasses, a nawet jeśli poprawisz FragmentPagerAdapter do nowej sytuacji, dodając przełącznik getItem () i inny przełącznik getPageTitle () (jak pokazano tutaj )

Ostrzeżenie: wspomniany wyżej klip zawiera błędy w kodzie, które wyjaśnię poniżej, ale warto zobaczyć, jak przejść od kodu domyślnego do kodu edytowalnego dla fragmentów z zakładkami)! Reszta mojej odpowiedzi ma o wiele większy sens, jeśli weźmiemy pod uwagę klasy Java i pliki XML z tego klipu (reprezentatywne dla pierwszego użycia fragmentów z kartami w scenariuszu dla początkujących).

Głównym powodem, dla którego najbardziej pozytywna odpowiedź z tej strony nie zadziała, jest to, że w tym domyślnym kodzie dla fragmentów z kartami fragmenty są używane w innej klasie Java: FragmentPagerAdapter!

Aby wysłać dane, masz ochotę utworzyć pakiet w MotherActivity i przekazać go w FragmentPagerAdapter, używając odpowiedzi nr 2.

Tyle tylko, że znowu jest źle. ( Prawdopodobnie można to zrobić w ten sposób, ale jest to tylko komplikacja, która tak naprawdę nie jest potrzebna ).

Myślę, że poprawnym / łatwiejszym sposobem jest przekazanie danych bezpośrednio do danego fragmentu przy użyciu odpowiedzi nr 2. Tak, będzie ścisłe powiązanie między Aktywnością a Fragmentem, ALE, dla fragmentów z zakładkami, jest to trochę oczekiwane. Radziłbym nawet utworzyć fragmenty z zakładkami w klasie Java MotherActivity (jako podklasy, ponieważ nigdy nie będą używane poza MotherActivity) - to proste, wystarczy dodać w klasie Java Java MotherActivity tyle fragmentów, ile potrzebujesz:

 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;
    }
}.

Tak więc, aby przekazać dane z MotherActivity do takiego fragmentu, musisz utworzyć prywatne Strings / Bundle powyżej OnCreate swojej aktywności Mother - które możesz wypełnić danymi, które chcesz przekazać do fragmentów, i przekazać je za pomocą Metoda utworzona po onCreate (tutaj nazywana getMyData ()).

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;
    }
}

A następnie w klasie fragmentu korzystasz z 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;
        }
    }

Jeśli masz zapytania do bazy danych, radzę wykonać je w MotherActivity (i przekazać wyniki jako Ciągi / liczby całkowite dołączone do kluczy w pakiecie, jak pokazano powyżej), ponieważ wewnątrz fragmentów z kartami twoja składnia stanie się bardziej złożona (staje się to getActivity () na przykład, a getIntent staje się getActivity (). getIntent), ale masz również opcję robienia tego, co chcesz.

Moja rada dla początkujących polega na skupieniu się na małych krokach. Najpierw zdobądź zamiar otwarcia bardzo prostej czynności na kartach, bez przekazywania ŻADNYCH danych. Czy to działa? Czy otwiera zakładki, których oczekujesz? Jeśli nie to dlaczego?

Zacznij od tego, a stosując rozwiązania, takie jak przedstawione w tym klipie , zobacz, czego brakuje. W przypadku tego konkretnego klipu plik mainactivity.xml nigdy nie jest wyświetlany. To z pewnością cię dezorientuje. Ale jeśli zwrócisz uwagę, zobaczysz, że na przykład kontekst (narzędzia: kontekst) jest niepoprawny w plikach fragmentów xml. Każdy fragment XML musi wskazywać prawidłową klasę fragmentu (lub podklasę za pomocą separatora $).

Zobaczysz również, że w głównej klasie java aktywności musisz dodać tabLayout.setupWithViewPager (mViewPager) - tuż po linii TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); bez tego wiersza widok nie jest faktycznie powiązany z plikami XML fragmentów, ale pokazuje TYLKO plik xml głównej aktywności.

Oprócz wiersza w głównej klasie java działania, w pliku XML głównej czynności musisz zmienić zakładki, aby dopasować je do swojej sytuacji (np. Dodać lub usunąć TabItems). Jeśli nie masz zakładek w głównym pliku XML działania, być może nie wybrałeś poprawnego typu działania, kiedy go utworzyłeś (nowe działanie - działanie z kartami).

Pamiętaj, że w ostatnich 3 akapitach mówię o filmie! Więc kiedy mówię XML głównej aktywności, jest to główny XML aktywności w filmie, którym w twojej sytuacji jest plik XML MotherActivity.

Adrian Stoica
źródło
8

Po przekazaniu odwołania do fragmentu (konkretnej podklasy) do zadania asynchronicznego można uzyskać bezpośredni dostęp do fragmentu.

Niektóre sposoby przekazywania odwołania do fragmentu do zadania asynchronicznego:

  • Jeśli Twoim zadaniem asynchronicznym jest pełnoprawna klasa ( class FooTask extends AsyncTask), przekaż swój fragment do konstruktora.
  • Jeśli Twoim zadaniem asynchronicznym jest klasa wewnętrzna, po prostu zadeklaruj końcową zmienną Fragment w zakresie, w którym zdefiniowane jest zadanie asynchroniczne, lub jako pole klasy zewnętrznej. Będziesz mógł uzyskać do niego dostęp z klasy wewnętrznej.
Jaskółka oknówka
źródło
Twoja odpowiedź wydaje mi się całkiem uzasadniona. Czy możesz trochę rozwinąć, podając przykładowy kod do zrobienia?
Leon Armstrong,
6

Czasami możesz otrzymać zamiar w swojej działalności i musisz przekazać informacje do działającego fragmentu.
Podane odpowiedzi są OK, jeśli chcesz rozpocząć fragment, ale jeśli nadal działa, setArguments()nie jest bardzo przydatny.
Kolejny problem występuje, jeśli przekazane informacje spowodują interakcję z interfejsem użytkownika. W takim przypadku nie możesz zadzwonićmyfragment.passData() ponieważ Android szybko powie, że tylko wątek, który utworzył widok, może wchodzić w interakcje.

Tak więc moją propozycją jest użycie odbiornika. W ten sposób możesz wysyłać dane z dowolnego miejsca, w tym z działania, ale zadanie zostanie wykonane w kontekście fragmentu.

W twoim fragmencie 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
    }
}

W tobie aktywność:

// somewhere
Intent retIntent = new Intent(RE_DATA);
retIntent.putExtra("data", myData);
sendBroadcast(retIntent);
fralbo
źródło
5

Bardzo stary post, wciąż śmiem dodawać małe wyjaśnienie, które byłoby dla mnie pomocne.

Technicznie możesz bezpośrednio ustawić członków dowolnego typu we fragmencie z aktywności.
Dlaczego więc pakiet?
Powód jest bardzo prosty - Pakiet zapewnia jednolity sposób obsługi:
- tworzenie / otwieranie fragmentu
- rekonfiguracja (obracanie ekranu) - po prostu dodaj początkowy / zaktualizowany pakiet do outState w onSaveInstanceState ()
- przywracanie aplikacji po pobraniu śmieci w tle ( jak w przypadku rekonfiguracji).

Możesz (jeśli lubisz eksperymenty) stworzyć obejście w prostych sytuacjach, ale podejście do pakietu po prostu nie widzi różnicy między jednym fragmentem a tysiącem na backstacku - pozostaje proste i jednoznaczne.
Dlatego odpowiedź @Elenasys jest najbardziej eleganckim i uniwersalnym rozwiązaniem.
I dlatego odpowiedź udzielona przez @Martin ma pułapki

sberezin
źródło
4

lepszym podejściem do przesyłania danych z klasy aktywności do fragmentu jest przekazywanie metodami ustawiającymi. Lubić

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

i łatwo uzyskaj te dane z klasy.

ssi-anik
źródło
Jak przesyłać dane z fragmentu do fragmentu, takie jak stackoverflow.com/questions/32953477/pass-data-to-fragment
Hoo
Nie jest to zbyt wygodne, gdy przechodzisz obok innych, wcześniej ustawionych Extra's
Gerard
Jeśli potrzebujesz ustawić te dane na jakieś pole w swoim fragmencie, a nie jest ono jeszcze widoczne (zainicjowane), otrzymasz NPE.
yozhik
Przestałem pracować z Androidem prawdopodobnie 3 lata temu, te rzeczy mogą być obecnie przestarzałe.
ssi-anik
4

Od Activitywysyłasz dane z pakietem jako:

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

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

A w Fragmentmetodzie onCreateView pobierz dane:

@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
źródło
3

Jeśli po inicjalizacji activitykonieczne jest fragmentwykonanie akcji, najprostszym sposobem jest activitywywołanie metody w fragmentinstancji. W fragmentdodaj metodę:

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

a następnie w activity, uzyskać dostęp do fragmentkorzystania z fragmentmenedżera i wywołać 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");
    }
}

a następnie activitymogą komunikować się bezpośrednio z fragment, wywołując to method.


źródło
1
jest to naprawdę miłe w tym sensie, że nie chcesz wchodzić w onCreateViewmetodę we fragmencie. był bardzo pomocny
Młody Emil
2

Użyj następującego interfejsu, aby komunikować się między aktywnością a fragmentem

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

Lub skorzystaj z tego ogólnego odbiornika do dwukierunkowej komunikacji za pomocą interfejsu

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

metoda pokazu fragmentów

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

można oddać swój kontekst GenericConnectorw onAttach(Context)zbyt

w twojej działalności

CustomValueDialogFragment.show(this);

w twoim fragmencie

...
@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");
        }

Uwaga: Nigdy nie używaj go w odpowiedni "".toString().toString().toString();sposób.

Qamar
źródło
2

natknąłem się na to pytanie, podczas gdy większość powyższych metod będzie działać. Chcę tylko dodać, że możesz używać Biblioteki zdarzeń , szczególnie w scenariuszach, w których komponent (działanie lub fragment) nie został utworzony, jest dobry dla wszystkich rozmiarów projektów na Androida i wielu przypadków użycia. Osobiście wykorzystałem go w kilku projektach, które mam w sklepie playstore.

Joshua Majebi
źródło
1

Możesz utworzyć publiczną metodę statyczną we fragmencie, w której uzyskasz statyczne odniesienie do tego fragmentu, a następnie przekażesz dane do tej funkcji i ustawisz te dane na argument w tej samej metodzie, i otrzymasz dane za pośrednictwem getArgument na oncreate metodą fragmentu, i ustaw te dane na lokalne zmienne.

M.Noman
źródło
1

Najmądrzejszym wypróbowanym i przetestowanym sposobem przekazywania danych między fragmentami a aktywnością jest utworzenie zmiennych, na przykład:

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

Następnie, aby przekazać dane z fragmentu do działania, robimy to w metodzie onActivityCreated:

//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;
    }

Teraz możesz uzyskać wartość StorageUtil.employees z dowolnego miejsca. Powodzenia!

Andrew Sam
źródło
0

Moim rozwiązaniem jest napisanie statycznej metody wewnątrz fragmentu:

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

W ten sposób jestem pewien, że wszystkie dane, których potrzebuję, znajdują się we fragmencie przed każdą inną możliwą operacją, która mogłaby wymagać pracy z nim. Również moim zdaniem wygląda to na czystsze.

Matteo
źródło
1
Cóż, jeśli TheData nie jest bezpieczny dla wątków, uczynienie go statycznym niekoniecznie ochroni cię przed problemami z wątkami. Ostrożnie z tym. Z natury statyczny nie jest bezpieczny dla wątków.
Martin Marconcini,
0

Wystąpił podobny problem podczas korzystania z najnowszego komponentu architektury Nawigacji. Wypróbowałem cały wyżej wymieniony kod, przekazując pakiet z mojej aktywności wywoływania do Fragment.

Najlepszym rozwiązaniem, zgodnym z najnowszymi trendami rozwojowymi w systemie Android, jest użycie View Model (część Androida Jetpack).

Utwórz i zainicjuj klasę ViewModel w działaniu nadrzędnym. Pamiętaj, że ten ViewModel musi być współużytkowany przez działanie i fragment.

Teraz, wewnątrz onViewCreated () fragmentu, zainicjuj ten sam ViewModel i ustaw Obserwatorów, aby nasłuchiwały pól ViewModel.

Oto przydatny, dogłębny samouczek, jeśli potrzebujesz.

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

devDeejay
źródło
-4

W swojej działalności zadeklaruj zmienną statyczną

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

Następnie w swoim fragmencie lubię podążać

ActivityName.contactItems.put(Number,contactsModal);
Dv Keerthi
źródło
Będzie działać, ale NIE ZALECANE. Ponieważ członkowie statyczni pozostaną w pamięci, chyba że aplikacja zostanie wymuszona z ostatnich aplikacji. W takim przypadku powinieneś używać członu statycznego tylko wtedy, gdy potrzebujesz go w wielu działaniach w całej aplikacji.
M Shaban Ali,