Saya menggunakan ViewPager kompatibilitas v4 di Android. FragmentActivity saya memiliki banyak data yang akan ditampilkan dengan cara berbeda pada halaman berbeda di ViewPager saya. Sejauh ini saya hanya memiliki 3 instance dari ListFragment yang sama, tetapi di masa depan saya akan memiliki 3 instance ListFragments yang berbeda. ViewPager berada di layar ponsel vertikal, daftar tidak berdampingan.
Sekarang tombol pada ListFragment memulai aktivitas satu halaman terpisah (melalui FragmentActivity), yang mengembalikan dan FragmentActivity memodifikasi data, menyimpannya, lalu mencoba memperbarui semua tampilan dalam ViewPager-nya. Di sinilah saya terjebak.
public class ProgressMainActivity extends FragmentActivity
{
MyAdapter mAdapter;
ViewPager mPager;
@Override
public void onCreate(Bundle savedInstanceState)
{
...
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.viewpager);
mPager.setAdapter(mAdapter);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
...
updateFragments();
...
}
public void updateFragments()
{
//Attempt 1:
//mAdapter.notifyDataSetChanged();
//mPager.setAdapter(mAdapter);
//Attempt 2:
//HomeListFragment fragment = (HomeListFragment) getSupportFragmentManager().findFragmentById(mAdapter.fragId[0]);
//fragment.updateDisplay();
}
public static class MyAdapter extends FragmentPagerAdapter implements
TitleProvider
{
int[] fragId = {0,0,0,0,0};
public MyAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public String getTitle(int position){
return titles[position];
}
@Override
public int getCount(){
return titles.length;
}
@Override
public Fragment getItem(int position)
{
Fragment frag = HomeListFragment.newInstance(position);
//Attempt 2:
//fragId[position] = frag.getId();
return frag;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE; //To make notifyDataSetChanged() do something
}
}
public class HomeListFragment extends ListFragment
{
...
public static HomeListFragment newInstance(int num)
{
HomeListFragment f = new HomeListFragment();
...
return f;
}
...
Sekarang seperti yang Anda lihat, upaya pertama saya adalah memberi tahuDataSetChanged pada seluruh FragmentPagerAdapter, dan ini menunjukkan untuk memperbarui data kadang-kadang, tetapi orang lain saya mendapat IllegalStateException: Tidak dapat melakukan tindakan ini setelah onSaveInstanceState.
Upaya kedua saya melibatkan mencoba untuk memanggil fungsi pembaruan di ListFragment saya, tetapi getId di getItem kembali 0. Sesuai dokumen yang saya coba dengan
memperoleh referensi ke Fragmen dari FragmentManager, menggunakan findFragmentById () atau findFragmentByTag ()
tapi saya tidak tahu tag atau id dari Fragmen saya! Saya memiliki android: id = "@ + id / viewpager" untuk ViewPager, dan android: id = "@ android: id / list" untuk ListView saya di tata letak ListFragment, tapi saya rasa ini tidak berguna.
Jadi, bagaimana saya bisa: a) memperbarui seluruh ViewPager dengan aman dalam sekali jalan (idealnya mengembalikan pengguna ke halaman sebelumnya) - tidak apa-apa jika pengguna melihat perubahan tampilan. Atau lebih disukai, b) memanggil fungsi di setiap ListFragment yang terpengaruh untuk memperbarui ListView secara manual.
Bantuan apa pun akan diterima dengan penuh syukur!
null
fragmen.FragmentPagerAdaper
tetapi gagal untukFragmentStatePagerAdaper
(Fragment.getTag()
selalu kembalinull
.Jawaban Barkside berfungsi dengan
FragmentPagerAdapter
tetapi tidak bekerjaFragmentStatePagerAdapter
, karena tidak menetapkan tag pada fragmen yang diteruskannyaFragmentManager
.Dengan
FragmentStatePagerAdapter
itu sepertinya kita bisa bertahan, menggunakaninstantiateItem(ViewGroup container, int position)
panggilannya. Ini mengembalikan referensi ke fragmen di posisiposition
. JikaFragmentStatePagerAdapter
sudah memegang referensi untuk fragmen yang dimaksud,instantiateItem
cukup kembalikan referensi ke fragmen itu, dan jangan panggilgetItem()
untuk membuat instance lagi.Jadi, misalkan, saya sedang melihat fragmen # 50, dan ingin mengakses fragmen # 49. Karena mereka dekat, ada kemungkinan besar # 49 akan sudah dipakai. Begitu,
sumber
FragmentStatePagerAdapter
, menggunakan kode di atas dengana.instantiateItem(viewPager, viewPager.getCurrentItem());
(untuk menghilangkan 49) seperti yang diusulkan oleh @ mblackwell8 bekerja dengan sempurna.instantiateItem
harus dikelilingi olehstartUpdate
/finishUpdate
panggilan. detail ada di jawaban saya untuk pertanyaan serupa: stackoverflow.com/questions/14035090/...OK, saya pikir saya telah menemukan cara untuk melakukan permintaan b) dalam pertanyaan saya sendiri jadi saya akan berbagi untuk kepentingan orang lain. Tag fragmen di dalam ViewPager ada di formulir
"android:switcher:VIEWPAGER_ID:INDEX"
, di manaVIEWPAGER_ID
adaR.id.viewpager
di tata letak XML, dan INDEX adalah posisi di viewpager. Jadi, jika posisinya diketahui (misalnya 0), saya dapat tampil diupdateFragments()
:Saya tidak tahu apakah ini cara yang valid untuk melakukannya, tetapi itu akan dilakukan sampai sesuatu yang lebih baik disarankan.
sumber
makeFragmentName
digunakan untuk menghasilkan Tag yang bisa Anda gunakan sebagai gantinya untuk pendekatan yang sedikit kurang-HomeListFragment fragment = (HomeListFragment) getSupportFragmentManager().findFragmentByTag(FragmentPagerAdapter.makeFragmentName(R.id.viewpager, 0));
makeFragmentName
adalahprivate static
metode, jadi Anda tidak bisa mendapatkan akses ke sana.Jika Anda bertanya kepada saya, solusi kedua pada halaman di bawah ini, melacak semua halaman fragmen "aktif", lebih baik: http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part -ii.html
Jawaban dari barkside terlalu membingungkan bagi saya.
Anda melacak semua halaman fragmen "aktif". Dalam hal ini, Anda melacak halaman fragmen di FragmentStatePagerAdapter, yang digunakan oleh ViewPager.
Untuk menghindari menyimpan referensi ke halaman fragmen "tidak aktif", kita perlu menerapkan metode destrItem (...) dari FragmentStatePagerAdapter:
... dan ketika Anda perlu mengakses halaman yang terlihat saat ini, Anda kemudian memanggil:
... di mana metode getFragment (int) MyAdapter terlihat seperti ini:
"
sumber
Oke, setelah menguji metode dengan @barkside di atas, saya tidak bisa membuatnya berfungsi dengan aplikasi saya. Lalu saya ingat bahwa aplikasi IOSched2012 menggunakan
viewpager
juga, dan di situlah saya menemukan solusi saya. Itu tidak menggunakan ID fragmen atau Tag karena ini tidak disimpan denganviewpager
cara yang mudah diakses.Inilah bagian -bagian penting dari aplikasi IOSched HomeActivity. Berikan perhatian khusus pada komentar , karena di situlah letak kunci .:
Dan simpan contoh Anda
Fragments
diFragmentPagerAdapter
seperti ini:Juga, ingatlah untuk menjaga
Fragment
panggilan Anda seperti:sumber
getItem()
tidak dipanggil setelah induk dibuat kembali karena perubahan siklus hidup. Lihat stackoverflow.com/a/24662049/236743 . Dalam contoh ini sebagian dilindungi untuk satu fragmen tetapi tidak untuk dua fragmen yang lainAnda dapat menyalin
FragmentPagerAdapter
dan memodifikasi beberapa kode sumber, menambahkangetTag()
metodesebagai contoh
kemudian perluas, timpa metode abstrak ini, tidak perlu takut dengan perubahan Grup Android
FragmentPageAdapter
kode sumber di masa depansumber
Juga berfungsi tanpa masalah:
di suatu tempat di tata letak fragmen halaman:
di onCreateView fragmen ():
dan metode untuk mengembalikan Fragmen dari ViewPager, jika ada:
sumber
Atau Anda dapat mengganti
setPrimaryItem
metode dariFragmentPagerAdapter
seperti:sumber
Saya ingin memberikan pendekatan saya jika itu dapat membantu orang lain:
Ini adaptor pager saya:
Dalam aktivitas saya, saya memiliki:
Kemudian untuk mendapatkan fragmen saat ini yang saya lakukan adalah:
sumber
Ini solusi saya karena saya tidak perlu melacak tab saya dan perlu menyegarkan semuanya.
sumber