Fragmen tampaknya sangat bagus untuk pemisahan logika UI menjadi beberapa modul. Namun seiring dengan ViewPager
siklus hidupnya masih berkabut bagi saya. Jadi pikiran Guru sangat dibutuhkan!
Edit
Lihat solusi bodoh di bawah ;-)
Cakupan
Aktivitas utama memiliki ViewPager
dengan fragmen. Fragmen-fragmen itu dapat menerapkan logika yang sedikit berbeda untuk aktivitas (kirim) lainnya, sehingga data fragmen diisi melalui antarmuka panggilan balik di dalam aktivitas. Dan semuanya bekerja dengan baik pada peluncuran pertama, tetapi! ...
Masalah
Ketika aktivitas dibuat ulang (misalnya tentang perubahan orientasi), maka lakukan juga ViewPager
fragmennya. Kode (Anda akan temukan di bawah) mengatakan bahwa setiap kali aktivitas dibuat, saya mencoba membuat ViewPager
adaptor fragmen baru sama dengan fragmen (mungkin ini masalahnya) tetapi FragmentManager sudah menyimpan semua fragmen ini di suatu tempat (di mana?) Dan memulai mekanisme rekreasi bagi mereka. Jadi mekanisme rekreasi memanggil fragmen "lama" diAttach, onCreateView, dll. Dengan panggilan antarmuka panggilan balik untuk menginisiasi data melalui metode yang diterapkan Aktivitas. Tetapi metode ini menunjuk ke fragmen yang baru dibuat yang dibuat melalui metode onCreate Activity.
Isu
Mungkin saya menggunakan pola yang salah tetapi bahkan buku Android 3 Pro tidak memiliki banyak tentang hal itu. Jadi, tolong , beri saya satu-dua pukulan dan tunjukkan bagaimana melakukannya dengan cara yang benar. Terimakasih banyak!
Kode
Aktifitas utama
public class DashboardActivity extends BasePagerActivity implements OnMessageListActionListener {
private MessagesFragment mMessagesFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
Logger.d("Dash onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_container);
new DefaultToolbar(this);
// create fragments to use
mMessagesFragment = new MessagesFragment();
mStreamsFragment = new StreamsFragment();
// set titles and fragments for view pager
Map<String, Fragment> screens = new LinkedHashMap<String, Fragment>();
screens.put(getApplicationContext().getString(R.string.dashboard_title_dumb), new DumbFragment());
screens.put(getApplicationContext().getString(R.string.dashboard_title_messages), mMessagesFragment);
// instantiate view pager via adapter
mPager = (ViewPager) findViewById(R.id.viewpager_pager);
mPagerAdapter = new BasePagerAdapter(screens, getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
// set title indicator
TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.viewpager_titles);
indicator.setViewPager(mPager, 1);
}
/* set of fragments callback interface implementations */
@Override
public void onMessageInitialisation() {
Logger.d("Dash onMessageInitialisation");
if (mMessagesFragment != null)
mMessagesFragment.loadLastMessages();
}
@Override
public void onMessageSelected(Message selectedMessage) {
Intent intent = new Intent(this, StreamActivity.class);
intent.putExtra(Message.class.getName(), selectedMessage);
startActivity(intent);
}
BasePagerActivity alias pembantu
public class BasePagerActivity extends FragmentActivity {
BasePagerAdapter mPagerAdapter;
ViewPager mPager;
}
Adaptor
public class BasePagerAdapter extends FragmentPagerAdapter implements TitleProvider {
private Map<String, Fragment> mScreens;
public BasePagerAdapter(Map<String, Fragment> screenMap, FragmentManager fm) {
super(fm);
this.mScreens = screenMap;
}
@Override
public Fragment getItem(int position) {
return mScreens.values().toArray(new Fragment[mScreens.size()])[position];
}
@Override
public int getCount() {
return mScreens.size();
}
@Override
public String getTitle(int position) {
return mScreens.keySet().toArray(new String[mScreens.size()])[position];
}
// hack. we don't want to destroy our fragments and re-initiate them after
@Override
public void destroyItem(View container, int position, Object object) {
// TODO Auto-generated method stub
}
}
Pecahan
public class MessagesFragment extends ListFragment {
private boolean mIsLastMessages;
private List<Message> mMessagesList;
private MessageArrayAdapter mAdapter;
private LoadMessagesTask mLoadMessagesTask;
private OnMessageListActionListener mListener;
// define callback interface
public interface OnMessageListActionListener {
public void onMessageInitialisation();
public void onMessageSelected(Message selectedMessage);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// setting callback
mListener = (OnMessageListActionListener) activity;
mIsLastMessages = activity instanceof DashboardActivity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
inflater.inflate(R.layout.fragment_listview, container);
mProgressView = inflater.inflate(R.layout.listrow_progress, null);
mEmptyView = inflater.inflate(R.layout.fragment_nodata, null);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// instantiate loading task
mLoadMessagesTask = new LoadMessagesTask();
// instantiate list of messages
mMessagesList = new ArrayList<Message>();
mAdapter = new MessageArrayAdapter(getActivity(), mMessagesList);
setListAdapter(mAdapter);
}
@Override
public void onResume() {
mListener.onMessageInitialisation();
super.onResume();
}
public void onListItemClick(ListView l, View v, int position, long id) {
Message selectedMessage = (Message) getListAdapter().getItem(position);
mListener.onMessageSelected(selectedMessage);
super.onListItemClick(l, v, position, id);
}
/* public methods to load messages from host acitivity, etc... */
}
Larutan
Solusi bodoh adalah menyimpan fragmen di dalam onSaveInstanceState (dari aktivitas host) dengan putFragment dan memasukkannya ke dalam onCreate via getFragment. Tapi saya masih punya perasaan aneh bahwa hal-hal yang seharusnya tidak berfungsi seperti itu ... Lihat kode di bawah ini:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager()
.putFragment(outState, MessagesFragment.class.getName(), mMessagesFragment);
}
protected void onCreate(Bundle savedInstanceState) {
Logger.d("Dash onCreate");
super.onCreate(savedInstanceState);
...
// create fragments to use
if (savedInstanceState != null) {
mMessagesFragment = (MessagesFragment) getSupportFragmentManager().getFragment(
savedInstanceState, MessagesFragment.class.getName());
StreamsFragment.class.getName());
}
if (mMessagesFragment == null)
mMessagesFragment = new MessagesFragment();
...
}