Saya memiliki dua kelas. Pertama adalah kegiatan kedua adalah fragmen di mana saya memiliki beberapa EditText
. Dalam kegiatan saya memiliki subclass dengan async-tugas dan metode doInBackground
saya mendapatkan beberapa hasil yang saya simpan ke variabel. Bagaimana saya dapat mengirim variabel ini dari subclass "aktivitas saya" untuk fragmen ini?
Dari Aktivitas anda mengirim data dengan maksud sebagai:
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
dan di Fragmen onCreateView metode:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
Anda juga dapat mengakses data aktivitas dari fragmen:
Aktivitas:
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;
}
}
Fragmen:
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;
}
}
Aku´ve menemukan banyak jawaban berikut @ stackoverflow.com tapi yang pasti ini adalah jawaban yang benar:
Aktivitas:
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();
Fragmen:
Membaca nilai pada fragmen
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = this.getArguments();
String myValue = bundle.getString("message");
...
...
...
}
atau hanya
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("message");
...
...
...
}
Jawaban ini mungkin terlalu terlambat. tapi itu akan berguna untuk pembaca masa depan.
Saya memiliki beberapa kriteria. Saya telah dikodekan untuk memilih file dari niat. dan file yang dipilih untuk diteruskan ke fragmen tertentu untuk proses lebih lanjut. saya memiliki banyak fragmen yang memiliki fungsi dari File yang memilih. pada saat itu , setiap kali memeriksa kondisi dan mendapatkan fragmen dan lulus dengan nilai yang cukup menjijikkan. jadi , saya telah memutuskan untuk lulus nilai menggunakan antarmuka.
Langkah 1: Membuat antarmuka pada Kegiatan Utama.
public interface SelectedBundle {
void onBundleSelect(Bundle bundle);
}
Langkah 2: Membuat SelectedBundle referensi pada Kegiatan yang Sama
SelectedBundle selectedBundle;
Langkah 3: membuat Metode dalam Kegiatan yang Sama
public void setOnBundleSelected(SelectedBundle selectedBundle) {
this.selectedBundle = selectedBundle;
}
Langkah 4: Perlu menginisialisasi SelectedBundle referensi yang semua fragmen perlu filepicker fungsi.Anda menempatkan kode ini pada fragmen onCreateView(..)
metode
((MainActivity)getActivity()).setOnBundleSelected(new MainActivity.SelectedBundle() {
@Override
public void onBundleSelect(Bundle bundle) {
updateList(bundle);
}
});
Langkah 5: onActivityResult dari MainActivity, lulus nilai-nilai ke fragmen menggunakan antarmuka.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
selectedBundle.onBundleSelect(bundle);
}
Thats semua. Melaksanakan setiap fragmen yang anda butuhkan pada FragmentClass. Anda yang besar. yang telah anda lakukan. WOW...
Ide dasar dari menggunakan Fragmen (F) adalah untuk menciptakan kembali diri mempertahankan komponen UI dalam aplikasi android. Fragmen ini terkandung dalam kegiatan dan ada yang umum(terbaik) cara membuat jalur komunikasi cara-cara dari A -> F dan F-A, Itu adalah suatu keharusan untuk Berkomunikasi antara F-F melalui Aktivitas karena kemudian hanya menjadi Fragmen dipisahkan dan mempertahankan diri.
Jadi lewat data dari A -> F akan sama seperti yang dijelaskan oleh ρяσѕρєя K. selain jawaban itu, Setelah penciptaan Fragmen dalam suatu Kegiatan, kita juga dapat menyampaikan data ke fragmen memanggil metode pada Fragmen.
Misalnya:
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
articleFrag.updateArticleView(position);
Yang terbaik dan nyaman pendekatan memanggil fragmen contoh dan mengirim data pada waktu itu. setiap fragmen secara default memiliki contoh metode
misalnya : jika anda fragmen nama MyFragment
jadi anda akan menelepon anda fragmen dari aktivitas seperti ini :
getSupportFragmentManager().beginTransaction().add(R.id.container, MyFragment.newInstance("data1","data2"),"MyFragment").commit();
*R. id.wadah adalah id saya FrameLayout
jadi di MyFragment.newInstance("data1","data2") anda dapat mengirim data ke fragmen dan fragmen anda mendapatkan data ini di 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;
}
dan kemudian di onCreate metode fragmen anda'll mendapatkan data:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
jadi sekarang mParam1 memiliki data1 dan mParam2 memiliki data2
sekarang anda dapat menggunakan ini mParam1 dan mParam2 dalam fragmen.
Jika anda melewati referensi (beton subclass dari) fragmen ke async task, anda kemudian dapat mengakses fragmen ini diatas.
Beberapa cara melewati fragmen referensi ke async task:
kelas FooTask meluas AsyncTask
), kemudian melewati fragmen ke konstruktor.Saya ingin menambahkan untuk pemula bahwa perbedaan antara 2 paling upvoted jawaban di sini adalah yang diberikan oleh penggunaan yang berbeda dari sebuah fragmen.
Jika anda menggunakan fragmen dalam java class di mana anda memiliki data yang ingin anda lulus, anda dapat menerapkan jawaban pertama untuk lulus data:
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
Namun jika anda menggunakan untuk contoh kode default yang diberikan oleh Android Studio untuk tab fragmen, kode ini tidak akan bekerja.
Ini tidak akan bekerja bahkan jika anda mengganti default PlaceholderFragment dengan anda FragmentClasses, dan bahkan jika anda benar FragmentPagerAdapter dengan situasi baru menambahkan saklar untuk getItem() dan lain beralih untuk getPageTitle() (seperti yang ditunjukkan [di sini][1])
Peringatan: klip yang disebutkan di atas memiliki kesalahan kode, yang saya jelaskan nanti di sini, tapi ini berguna untuk melihat bagaimana anda pergi dari kode default untuk diedit kode untuk tab fragmen)! Sisa dari jawaban saya jauh lebih masuk akal jika anda mempertimbangkan kelas java dan xml file dari klip (perwakilan untuk penggunaan pertama dari tab fragmen oleh seorang pemula skenario).
Alasan utama yang paling upvoted jawaban dari halaman ini tidak akan bekerja adalah bahwa dalam kode default untuk tab fragmen, fragmen yang digunakan dalam java class: FragmentPagerAdapter!
Jadi, dalam rangka untuk mengirim data, anda tergoda untuk membuat bundel dalam MotherActivity dan menyebarkannya di FragmentPagerAdapter, menggunakan jawabannya tidak ada.2.
Hanya yang salah lagi. (Mungkin anda bisa melakukan hal seperti itu, tapi itu hanya sebuah komplikasi yang tidak benar-benar diperlukan).
Yang benar/cara yang lebih mudah untuk melakukannya, saya pikir, adalah untuk melewati data langsung ke fragmen dalam pertanyaan, menggunakan jawabannya tidak ada.2. Ya, akan ada kopling ketat antara Aktivitas dan Fragmen, TAPI, untuk tab fragmen, yang lebih baik dari yang diharapkan. Saya akan saran anda untuk membuat tab fragmen dalam MotherActivity kelas java (sebagai subclass, karena mereka tidak akan digunakan di luar MotherActivity) - sangat mudah, hanya menambahkan dalam MotherActivity jawa kelas banyak Fragmen yang anda butuhkan seperti ini:
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;
}
}.
Jadi, untuk melewatkan data dari MotherActivity untuk Fragmen tersebut anda akan perlu untuk membuat pribadi String/Bundel atas onCreate dari Ibumu aktivitas yang dapat anda isi dengan data yang anda inginkan untuk lolos ke fragmen, dan meneruskannya melalui metode yang diciptakan setelah onCreate (di sini disebut 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;
}
}
Dan kemudian di fragmen kelas, anda menggunakan 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;
}
}
Jika anda memiliki database permintaan saya saran anda untuk melakukannya di MotherActivity (dan lulus hasil mereka sebagai String/Integer melekat kunci dalam bundel seperti yang ditunjukkan di atas), karena di dalam tab fragmen, sintaks anda akan menjadi lebih kompleks (ini menjadi getActivity() misalnya, dan getIntent menjadi getActivity().getIntent), tetapi anda juga memiliki pilihan untuk melakukan seperti yang anda inginkan.
Saran saya untuk pemula adalah untuk fokus pada langkah-langkah kecil. Pertama, mendapatkan niat anda untuk membuka sangat sederhana tab aktivitas, tanpa melewati SETIAP data. Apakah itu bekerja? Apakah itu buka tab yang anda harapkan? Jika tidak, mengapa?
Mulai dari itu, dan dengan menerapkan solusi seperti yang disajikan dalam [clip][1], melihat apa yang hilang. Untuk itu khususnya klip, mainactivity.xml tidak pernah ditampilkan. Yang pasti akan membingungkan anda. Tetapi jika anda memperhatikan, anda akan melihat bahwa misalnya konteks (tools:context) adalah salah dalam xml file fragmen. Masing-masing fragmen XML perlu titik untuk benar fragmen kelas (atau subclass menggunakan separator $).
Anda juga akan melihat bahwa dalam kegiatan utama jawa kelas yang anda butuhkan untuk menambah tabLayout.setupWithViewPager(mViewPager) - tepat setelah baris TabLayout tabLayout = (TabLayout) findViewById(R. id.tab); tanpa baris ini, anda lihat adalah benar-benar tidak terkait dengan file XML dari fragmen, tapi itu HANYA menunjukkan file xml dari kegiatan utama.
Selain garis dalam kegiatan utama jawa kelas, pada kegiatan utama file XML yang anda butuhkan untuk mengubah tab sesuai dengan situasi anda (misalnya menambahkan atau menghapus TabItems). Jika anda tidak memiliki tab di bagian utama aktivitas XML, maka mungkin anda tidak memilih dengan tepat jenis aktivitas ketika anda buat itu di tempat pertama (aktivitas baru - tab activity).
Harap dicatat bahwa dalam terakhir 3 paragraf saya berbicara tentang video! Jadi ketika saya mengatakan kegiatan utama XML, itu adalah kegiatan utama XML dalam video tersebut, yang dalam situasi anda adalah MotherActivity file XML.
Dari Aktivitas
anda mengirim data dengan Bundel sebagai:
Bundle bundle = new Bundle();
bundle.putString("data", "Data you want to send");
// Your fragment
MyFragment obj = new MyFragment();
obj.setArguments(bundle);
Dan di Fragmen
onCreateView metode mendapatkan data:
@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);
}
Sangat lama posting, saya masih berani untuk menambahkan sedikit penjelasan yang telah membantu bagi saya.
Secara teknis anda dapat langsung mengatur anggota dari setiap jenis dalam sebuah fragmen dari kegiatan.
Jadi mengapa Bundel?
Alasannya sangat sederhana - Bundle menyediakan cara seragam untuk menangani:
- menciptakan/membuka fragmen
-- rekonfigurasi (rotasi layar) - hanya menambahkan awal/diperbarui bundel untuk outState di onSaveInstanceState()
-- aplikasi pemulihan setelah sampah dikumpulkan di latar belakang (dengan perbaikan).
Anda dapat (jika anda suka eksperimen) membuat solusi dalam situasi sederhana tapi Bundle-pendekatan hanya doesn't melihat perbedaan antara satu fragmen dan satu ribu di backstack - hal tetap sederhana dan mudah.
Yang's mengapa jawaban oleh @Elenasys adalah yang paling elegan dan solusi universal.
Dan's mengapa jawaban yang diberikan oleh @Martin memiliki jebakan
pendekatan yang lebih baik untuk mengirimkan data dari aktivitas kelas untuk fragmen lewat via penyetel. Seperti
FragmentClass fragmentClass = new FragmentClass();
fragmentClass.setMyList(mylist);
fragmentClass.setMyString(myString);
fragmentClass.setMyMap(myMap);
dan mendapatkan data ini dari kelas dengan mudah.
Kadang-kadang anda dapat menerima Niat dalam aktivitas anda dan anda harus lulus info untuk anda yang bekerja fragmen.
Diberikan jawaban yang OK jika anda perlu untuk memulai fragmen tapi jika itu's masih bekerja, setArguments()
adalah tidak sangat berguna.
Masalah lain terjadi jika melewati informasi akan menyebabkan untuk berinteraksi dengan teman UI. Dalam hal ini anda tidak bisa menyebut sesuatu seperti myfragment.passData()
karena android akan cepat mengatakan bahwa hanya benang yang menciptakan pandangan yang dapat berinteraksi dengan.
Jadi usulan saya adalah dengan menggunakan receiver. Dengan cara itu, anda dapat mengirim data dari mana saja, termasuk aktivitas, tapi pekerjaan yang akan dilakukan dalam fragmen's konteks.
Anda di fragmen'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
}
}
Dalam aktivitas anda:
// somewhere
Intent retIntent = new Intent(RE_DATA);
retIntent.putExtra("data", myData);
sendBroadcast(retIntent);
Jika suatu aktivitas
yang dibutuhkan untuk membuat sebuah fragmen
melakukan tindakan setelah inisialisasi, cara termudah adalah dengan memiliki aktivitas
memanggil metode fragmen
misalnya. Di fragmen
, menambahkan metode:
public class DemoFragment extends Fragment {
public void doSomething(String param) {
// do something in fragment
}
}
dan kemudian di aktivitas
, mendapatkan akses ke fragmen
menggunakan fragmen
manajer dan memanggil metode
:
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");
}
}
dan kemudian aktivitas
dapat berkomunikasi secara langsung dengan fragmen
dengan menerapkan ini metode
.
Cerdas cara dicoba dan diuji lewat data antara fragmen dan kegiatan ini adalah untuk membuat sebuah variabel,contoh:
class StorageUtil {
public static ArrayList<Employee> employees;
}
Kemudian untuk melewatkan data dari fragmen untuk kegiatan, kami melakukannya di onActivityCreated metode:
//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;
}
Sekarang anda bisa mendapatkan nilai StorageUtil.karyawan dari mana-mana. Goodluck!
Anda dapat membuat publik statis metode dalam fragmen di mana anda akan mendapatkan statis referensi dari fragmen dan kemudian meneruskan data ke fungsi itu dan menetapkan bahwa data untuk argumen dalam metode yang sama dan mendapatkan data melalui getArgument pada oncreate dari fragmen, dan mengatur data ke variabel lokal.
Menggunakan antarmuka berikut untuk berkomunikasi antara aktivitas dan fragmen
public interface BundleListener {
void update(Bundle bundle);
Bundle getBundle();
}
Atau gunakan berikut ini generik pendengar untuk komunikasi dua arah menggunakan antarmuka
/**
* Created by Qamar4P on 10/11/2017.
*/
public interface GenericConnector<T,E> {
T getData();
void updateData(E data);
void connect(GenericConnector<T,E> connector);
}
fragmen menunjukkan metode
public static void show(AppCompatActivity activity) {
CustomValueDialogFragment dialog = new CustomValueDialogFragment();
dialog.connector = (GenericConnector) activity;
dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
}
anda dapat memberikan konteks untuk GenericConnector
di onAttach(Konteks)
terlalu
dalam aktivitas anda
CustomValueDialogFragment.show(this);
dalam fragmen
...
@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");
}
Catatan: jangan Pernah menggunakan itu seperti "".toString().toString().toString();
jalan.
Solusi saya adalah untuk menulis sebuah metode statis di dalam fragmen:
public TheFragment setData(TheData data) {
TheFragment tf = new TheFragment();
tf.data = data;
return tf;
}
Dengan cara ini saya yakin bahwa semua data yang saya butuhkan adalah di dalam Fragmen sebelum yang lain mungkin operasi yang bisa perlu untuk bekerja dengan itu. Juga terlihat bersih menurut saya.
Aku berlari ke dalam masalah yang serupa saat menggunakan Navigasi terbaru arsitektur komponen. Mencoba semua yang disebutkan di atas kode dengan melewati bundel dari aktivitas menelepon ke Fragmen.
Solusi terbaik, berikut perkembangan terbaru tren di Android, dengan menggunakan View Model (bagian dari Android Jetpack).
Membuat dan Menginisialisasi sebuah ViewModel kelas induk Kegiatan, Harap dicatat bahwa ini ViewModel harus dibagi antara aktivitas dan fragmen.
Sekarang, di Dalam onViewCreated() fragmen, Menginisialisasi Sama ViewModel dan setup Pengamat untuk mendengarkan ViewModel bidang.
Berikut ini adalah membantu, tutorial mendalam jika anda membutuhkan.
saja menemukan pertanyaan ini, sementara kebanyakan dari metode-metode di atas akan bekerja. Saya hanya ingin menambahkan bahwa anda dapat menggunakan Event Bus Perpustakaan, terutama dalam skenario di mana komponen (Kegiatan atau Fragmen) belum dibuat, baik untuk semua ukuran dari proyek android dan banyak kasus penggunaan. Saya pribadi telah digunakan dalam beberapa proyek yang saya miliki di playstore.
Dalam aktivitas anda mendeklarasikan variabel statis
public static HashMap<String,ContactsModal> contactItems=new HashMap<String, ContactsModal>();
Kemudian di fragmen anda lakukan seperti mengikuti
ActivityName.contactItems.put(Number,contactsModal);