Các đoạn dường như rất hay để tách logic UI thành một số mô-đun. Nhưng cùng với ViewPager
vòng đời của nó vẫn còn mù mờ đối với tôi. Vì vậy, những suy nghĩ của Đạo sư rất cần thiết!
Biên tập
Xem giải pháp ngu ngốc dưới đây ;-)
Phạm vi
Hoạt động chính có một ViewPager
mảnh. Các đoạn đó có thể triển khai logic khác nhau một chút cho các hoạt động (chìm) khác, vì vậy dữ liệu của các đoạn được điền thông qua giao diện gọi lại bên trong hoạt động. Và mọi thứ hoạt động tốt trong lần ra mắt đầu tiên, nhưng! ...
Vấn đề
Khi hoạt động được tạo lại (ví dụ: thay đổi hướng) ViewPager
, các mảnh vỡ cũng vậy. Mã (bạn sẽ tìm thấy bên dưới) nói rằng mỗi khi hoạt động được tạo, tôi cố gắng tạo ViewPager
bộ điều hợp đoạn mới giống như đoạn (có thể đây là vấn đề) nhưng FragmentManager đã lưu trữ tất cả các đoạn này ở đâu đó (ở đâu?) Và bắt đầu cơ chế giải trí cho những người. Vì vậy, cơ chế giải trí gọi đoạn "cũ" là onAttach, onCreateView, v.v. bằng lệnh gọi giao diện gọi lại của tôi để bắt đầu dữ liệu thông qua phương thức được triển khai của Activity. Nhưng phương thức này chỉ ra đoạn mới được tạo thông qua phương thức onCreate của Activity.
Vấn đề
Có thể tôi đang sử dụng sai mẫu nhưng ngay cả sách Android 3 Pro cũng không có nhiều về nó. Vì vậy, xin vui lòng , cho tôi một hai cú đấm và chỉ ra làm thế nào để làm điều đó đúng cách. Cảm ơn nhiều!
Mã
Hoạt động chính
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 người trợ giúp
public class BasePagerActivity extends FragmentActivity {
BasePagerAdapter mPagerAdapter;
ViewPager mPager;
}
Bộ chuyển đổi
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
}
}
Miếng
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... */
}
Giải pháp
Giải pháp ngu ngốc là lưu các đoạn bên trong onSaveInstanceState (của máy chủ Hoạt động) với putFragment và đưa chúng vào bên trong onCreate thông qua getFragment. Nhưng tôi vẫn có một cảm giác kỳ lạ rằng mọi thứ không nên hoạt động như vậy ... Xem mã dưới đây:
@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();
...
}