UI mantığının bazı modüllere ayrılması için parçalar çok hoş görünüyor. Ancak ViewPager
yaşam döngüsü ile birlikte bana hala puslu. Bu yüzden Guru düşüncelerine çok ihtiyaç var!
Düzenle
Aşağıdaki aptal çözüme bakın ;-)
Dürbün
Ana faaliyetin bir ViewPager
fragmanları vardır. Bu fragmanlar diğer (alt alan) aktiviteler için biraz farklı bir mantık uygulayabilir, böylece fragmanların verileri aktivite içindeki bir geri arama arayüzü aracılığıyla doldurulur. Ve ilk lansmanda her şey iyi çalışıyor, ama! ...
Sorun
Etkinlik yeniden oluşturulduğunda (örn. Yönelim değişikliği gibi) ViewPager
parçaları da öyle. Kod (aşağıda bulacaksınız), etkinlik her oluşturulduğunda ViewPager
, parçalarla aynı yeni bir parça bağdaştırıcısı oluşturmaya çalıştığımı söylüyor (belki de sorun budur), ancak FragmentManager zaten tüm bu parçaların bir yerde (nerede?) Saklandığını ve bunlar için rekreasyon mekanizmasını başlatır. Bu nedenle, rekreasyon mekanizması, aktivitenin uygulanmış yöntemi aracılığıyla veri başlatmak için geri arama arabirim çağrısıyla "eski" parçanın onAttach, onCreateView, vb. Ancak bu yöntem, Etkinliğin onCreate yöntemiyle oluşturulan yeni oluşturulan parçayı gösterir.
Konu
Belki de yanlış desenler kullanıyorum, ancak Android 3 Pro kitabında bile bu konuda çok fazla şey yok. Yani, lütfen bana bir-iki yumruk vermek ve bunu doğru şekilde nasıl yapılacağını işaret etmektedir. Çok teşekkürler!
kod
Ana aktivite
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 aka yardımcı
public class BasePagerActivity extends FragmentActivity {
BasePagerAdapter mPagerAdapter;
ViewPager mPager;
}
adaptör
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
}
}
fragman
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... */
}
Çözüm
Aptal çözüm, putFragment ile (Host Aktivitesinin) onSaveInstanceState içindeki parçaları kaydetmek ve getFragment aracılığıyla onCreate içinde onları almaktır. Ama hala işlerin böyle çalışmaması gerektiği garip bir his var ... Aşağıdaki koda bakınız:
@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();
...
}