Am două clase. În primul rând este o activitate, al doilea este un fragment unde am niște EditText
. În activitatea am o subclasă cu async-sarcină și în metoda doInBackground
am obține un rezultat, pe care l-am salvat în variabilă. Cum pot trimite această variabilă din subclasa "activitatea mea" în acest fragment?
Din Activitatea de a te trimite date cu intenția ca:
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
și în Fragmentul onCreateView metoda:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
De asemenea, puteți accesa datele de activitate din fragment:
Activitate:
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;
}
}
Am´am găsit o mulțime de răspunsuri aici @ stackoverflow.com dar cu siguranta acesta este răspunsul corect:
Activitate:
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:
Citiți valoarea în fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = this.getArguments();
String myValue = bundle.getString("message");
...
...
...
}
sau doar
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("message");
...
...
...
}
Acest răspuns poate fi prea târziu. dar va fi util pentru viitorii cititori.
Am niște criterii. Trebuie codificate pentru a alege fișierul de intenție. și fișierul selectat pentru a fi trecut la anumit fragment pentru continuarea procesului. am multe fragmente având funcționalitatea de Fișier cules. la timp , de fiecare dată când verificarea stării și a obține fragment și se trece valoarea este destul de dezgustător. deci , am decis pentru a trece valoarea folosind interfata.
Pasul 1: Crea interfata Principal de Activitate.
public interface SelectedBundle {
void onBundleSelect(Bundle bundle);
}
Pasul 2: Crea SelectedBundle trimitere la Aceeași Activitate
SelectedBundle selectedBundle;
Pasul 3: crearea Metoda în Aceeași Activitate
public void setOnBundleSelected(SelectedBundle selectedBundle) {
this.selectedBundle = selectedBundle;
}
Pasul 4: Trebuie să pornim SelectedBundle de referință care sunt toate fragment nevoie filepicker funcționalitate.Puneți acest cod pe site-fragment onCreateView(..)
metoda
((MainActivity)getActivity()).setOnBundleSelected(new MainActivity.SelectedBundle() {
@Override
public void onBundleSelect(Bundle bundle) {
updateList(bundle);
}
});
Pasul 5: onActivityResult din MainActivity, trece valori fragmente folosind interfata.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
selectedBundle.onBundleSelect(bundle);
}
Asta-i tot. Pună în aplicare fiecare fragment ai nevoie pe FragmentClass. Ești mare. ai făcut. WOW...
Ideea de bază de a folosi Fragmente (F) este de a crea reutilizabile de sine stătătoare componente UI în aplicații android. Aceste Fragmente sunt incluse în activități și nu sunt frecvente(cel mai bun) mod de a crea o cale de comunicare moduri de A -> F și F-O, este o necesitate de a Comunica între F-F printr-o Activitate pentru că atunci doar Fragmente decuplat și de sine stătătoare.
Deci trecerea datelor de la Un -> F este de gând să fie la fel ca a explicat de ρяσѕρєя K. În plus față de acest răspuns, După crearea de Fragmente în interiorul o Activitate, putem trece, de asemenea, date de la fragmente de metode de asteptare în Fragmente.
De exemplu:
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
articleFrag.updateArticleView(position);
Cel mai bun și convenabil abordare este de asteptare fragment de exemplu, și trimite date la acel moment. fiecare fragment implicit au metodă de instanță
De exemplu : dacă fragmentul este numele MyFragment
așa că va suna fragment de activitate astfel :
getSupportFragmentManager().beginTransaction().add(R.id.container, MyFragment.newInstance("data1","data2"),"MyFragment").commit();
*R. id.containerul este un id-ul meu FrameLayout
deci, în MyFragment.newInstance("data1","data2") puteți trimite date la un fragment și în fragment veți obține aceste date 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;
}
și apoi, în onCreate metoda de fragment tine'll a obține date:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
deci acum mParam1 au date1 și mParam2 au date2
acum puteți utiliza acest mParam1 și mParam2 în fragment.
Dacă trece o referință la (beton subclasă a) fragment în asincron sarcina, puteți accesa apoi fragmentul direct.
Unele moduri de a trece fragment de referință în asincron sarcina:
Aș dori să adaug pentru incepatori că diferența dintre 2 cele mai upvoted răspunsuri aici este dat de utilizarea diferită a unui fragment.
Dacă utilizați fragment în clasa java în cazul în care aveți date pe care doriți să treacă, puteți aplica primul răspuns a trece de date:
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
Cu toate acestea, dacă utilizați, de exemplu, codul implicit dat de Android Studio pentru file fragmente, acest cod nu va funcționa.
Acesta nu va funcționa chiar dacă înlocuiți implicit PlaceholderFragment cu FragmentClasses, și chiar dacă a corecta FragmentPagerAdapter la noua situație adăugarea unui comutator pentru getItem() și un întrerupător pentru getPageTitle() (așa cum se arată aici)
Avertisment: acest clip a menționat mai sus a erorilor de cod, ceea ce explic eu mai târziu aici, dar este util pentru a vedea cum te duci din codul implicit editabile cod pentru file fragmente)! Restul de răspunsul meu face mult mai mult sens dacă te gândești la clase java și xml fișierele din acel clip (reprezentativ pentru o prima utilizare a file fragmente de un incepator scenariu).
Principalul motiv pentru care cele mai upvoted răspunsul la această pagină nu va funcționa este că în codul implicit pentru file fragmente, fragmente sunt utilizate într-o altă clasă java: FragmentPagerAdapter!
Deci, în scopul de a trimite datele, ești tentat să creați un pachet în MotherActivity și trece-l în FragmentPagerAdapter, folosind răspunsul nr.2.
Numai că este greșit din nou. (Probabil ai putea face asta, dar este doar o complicație care nu este cu adevărat necesar).
Corect/mai ușor mod de a face acest lucru, cred, este de a trece de date direct în fragmentul în cauză, folosind răspunsul nr.2. Da, nu va fi strânsă între Activitate și Fragmentul, DAR, pentru file fragmente, care este un fel de așteptat. Chiar mi-ar sfat ai pentru a crea file fragmente în interiorul MotherActivity clasa java (ca subclase, ca nu vor fi folosite niciodată în afara MotherActivity) - este ușor, trebuie doar să adăugați în interiorul MotherActivity clasa java cât mai multe Fragmente ca ai nevoie de genul asta:
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;
}
}.
Deci, pentru a trece de date de la MotherActivity la o astfel de Fragment, va trebui să creați privat Siruri de caractere/Pachete de mai sus onCreate de Mama ta activitate - pe care le puteți umple cu datele pe care doriți pentru a trece la fragmente, și trece-le printr-o metodă creat după onCreate (aici numit 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;
}
}
Și apoi, în fragmentul de clasă, utilizați 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;
}
}
Dacă aveți interogări de baze de date te sfătuiesc să le facă în MotherActivity (și trece rezultatele lor, ca Siruri de caractere/numere Întregi atașat la chei în interiorul unui pachet așa cum este arătat mai sus), ca în interiorul file fragmente, sintaxa va deveni mult mai complex (acest lucru devine getActivity() de exemplu, și getIntent devine getActivity().getIntent), dar trebuie, de asemenea, opțiunea de a face cum doriți.
Sfatul meu pentru incepatori este de a se concentra pe pași mici. În primul rând, ia-ți intenția de a deschide un foarte simplu file de activitate, fără a trece ORICE date. Funcționează? Se deschide filele te astepti? Dacă nu, de ce?
Începe de la care, și prin aplicarea de soluții, cum ar fi cele prezentate în clip, a se vedea ceea ce lipsește. Pentru acea clip, mainactivity.xml este mai arătat. Care cu siguranta va vor confunda. Dar dacă acordați atenție, veți vedea că, de exemplu, contextul (instrumente:context) este greșit în xml fragmente de fișiere. Fiecare fragment XML trebuie să indice corect fragment de clasă (sau subclasa folosind separatorul $).
Veți vedea, de asemenea, că, în principal, activitatea de clasă java aveți nevoie pentru a adăuga tabLayout.setupWithViewPager(mViewPager) - imediat dupa linia de TabLayout tabLayout = (TabLayout) findViewById(R. id.file); fără această linie, punctul dumneavoastră de vedere este, de fapt, nu sunt legate de fișierele XML de fragmente, dar arată DOAR fișierul xml din domeniul principal de activitate.
În plus față de linia din domeniul principal de activitate din clasa java, din domeniul principal de activitate fișier XML aveți nevoie pentru a schimba file pentru a se potrivi situația dumneavoastră (de exemplu, adăuga sau elimina TabItems). Dacă nu aveți file din domeniul principal de activitate XML, atunci este posibil să nu aleagă corect tipul de activitate atunci când l-a creat, în primul rând (nouă activitate - file de activitate).
Vă rugăm să rețineți că în ultimele 3 paragrafe vorbesc despre video! Așa că atunci când am spus principal de activitate XML, este domeniul principal de activitate XML în video, care în situația ta este MotherActivity fișier XML.
De "Activitate" a te trimite date cu Pachet fi:
Bundle bundle = new Bundle();
bundle.putString("data", "Data you want to send");
// Your fragment
MyFragment obj = new MyFragment();
obj.setArguments(bundle);
Și în "Fragmente" onCreateView metodă de a obține date:
@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);
}
Foarte vechi post, încă îndrăznesc să adăugați un pic de explicație, care ar fi fost util pentru mine.
Din punct de vedere tehnic, puteți seta direct membrii de orice tip într-un fragment din activitate.
Deci, de ce Pachet?
Motivul este foarte simplu - Pachet oferă o modalitate uniformă să se ocupe de:
-- crearea/deschiderea fragment
-- reconfigurare (rotația ecranului) - trebuie doar să adăugați inițială/actualizat pachet pentru outState în onSaveInstanceState()
Puteți (dacă vă place experimente) a crea o soluție în situații simple, dar Bundle-abordare nu't vedea diferenta intre un fragment și una de mii pe un backstack - rămâne simplă și directă.
Ca's de ce răspunsul de @Elenasys este cel mai elegant și soluție universală.
Și's de ce răspunsul dat de @Martin a capcane
cea mai bună abordare pentru trimiterea de date de la o activitate la clasa a fragment trece prin metode setter. Ca
FragmentClass fragmentClass = new FragmentClass();
fragmentClass.setMyList(mylist);
fragmentClass.setMyString(myString);
fragmentClass.setMyMap(myMap);
și a obține aceste date de la clasa cu ușurință.
Uneori, puteți primi Intenție în activitatea dumneavoastră și aveți nevoie pentru a trece info de lucru fragment.
Răspunsurile date sunt OK, dacă aveți nevoie pentru a începe fragment, dar dacă-l's încă de lucru, setArguments()
nu este foarte util.
O altă problemă apare în cazul în care a trecut de informații va cauza pentru a interacționa cu UI. În acest caz nu poți spune ceva de genul myfragment.passData()
pentru că android va spune repede că doar firul care a creat vedere poate interacționa cu.
Deci, propunerea mea este de a folosi un receptor. În acest fel, puteți trimite datele de oriunde, inclusiv activitatea, dar de locuri de muncă va fi făcut în cadrul fragment's de context.
În tine fragment's 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
}
}
În tine activitatea:
// somewhere
Intent retIntent = new Intent(RE_DATA);
retIntent.putExtra("data", myData);
sendBroadcast(retIntent);
Dacă o "activitate" are nevoie pentru a face un "fragmente" de a efectua o acțiune după inițializare, cel mai simplu mod este de a avea "activitate" invoca o metodă pe "fragmente" de exemplu. În "fragmente", adaugă o metoda:
public class DemoFragment extends Fragment {
public void doSomething(String param) {
// do something in fragment
}
}
și apoi, în "activitate", pentru a primi acces la "fragmente" ajutorul "fragmente" de manager și de apel "metoda":
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");
}
}
și apoi, "activitate" poate comunica direct cu "fragmente" prin invocarea această "metodă".
Mai deștept încercat și testat de a trece de date între fragmente și activități este de a crea un variabile,de exemplu:
class StorageUtil {
public static ArrayList<Employee> employees;
}
Apoi, pentru a trece de date de la fragment la activitate, vom face acest lucru în onActivityCreated metoda:
//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;
}
Acum puteți obține valoarea de StorageUtil.angajații de pretutindeni. Goodluck!
Puteți crea public metodă statică în fragment în cazul în care veți obține de referință statică de acel fragment și apoi se trec datele la care funcția și a stabilit că datele argument în aceeași metodă și obține date prin intermediul getArgument pe metoda oncreate de fragment, și a stabilit datele pentru variabilele locale.
Utilizați interfața de mai jos pentru a comunica între activitate și fragment
public interface BundleListener {
void update(Bundle bundle);
Bundle getBundle();
}
Sau de a folosi următoarele acest generic ascultător pentru două sensuri de comunicare folosind interfata
/**
* 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 metoda de spectacol
public static void show(AppCompatActivity activity) {
CustomValueDialogFragment dialog = new CustomValueDialogFragment();
dialog.connector = (GenericConnector) activity;
dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
}
puteți arunca context `GenericConnector " în " onAttach(Context) prea
în activitatea dvs.
CustomValueDialogFragment.show(this);
în 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");
}
Notă: nu utilizați Niciodată ca"".toString().toString().toString();` cale.
Soluția mea este să scriu o metodă statică în interiorul fragment:
public TheFragment setData(TheData data) {
TheFragment tf = new TheFragment();
tf.data = data;
return tf;
}
În acest fel sunt sigur că toate datele de care am nevoie este în interiorul Fragment înainte de orice alte operațiuni care ar putea avea nevoie pentru a lucra cu ea. De asemenea, pare mai curat, în opinia mea.
Am fugit într-o problemă similară în timp ce folosind cele mai recente de Navigare arhitectura componentă. A încercat toate cele de mai sus-menționat codul cu care trece un pachet de la chemarea mea activitate la Fragment.
Cea mai bună soluție, în urma cele mai recente tendințe de dezvoltare în Android, este de a folosi Modelul Vedere (parte de Android Jetpack).
Crea și de a Inițializa un ViewModel clasă în Activitatea părinte, vă Rugăm să rețineți că acest ViewModel trebuie să fie partajată între activitate și fragment.
Acum, în Interiorul onViewCreated() a fragmentului, a Inițializa Același ViewModel și configurare Observatori pentru a asculta ViewModel domenii.
Aici este un ajutor, tutorial în profunzime, dacă aveți nevoie.
dat peste această întrebare, în timp ce cele mai multe dintre metodele de mai sus va funcționa. Vreau doar să adaug că puteți utiliza Eveniment Autobuz Biblioteca, în special în scenarii în cazul în care componenta (Activitate sau Fragment) nu a fost creat, bun pentru toate dimensiunile de proiecte android și multe cazuri de utilizare. Eu personal am folosit-o în mai multe proiecte am pe playstore.
În activitatea declara variabile statice
public static HashMap<String,ContactsModal> contactItems=new HashMap<String, ContactsModal>();
Apoi, în fragmentul face ca urma
ActivityName.contactItems.put(Number,contactsModal);