我在ViewPager
中有5个片段,用来逐步填充业务对象的多个字段,每一步都会设置其中一些字段。我阅读了许多关于片段之间通信的文章,但并不喜欢其他人提倡的方式,所以在思考如何在我的情况下处理这个问题后,我最终开始考虑使用单例模式对象,在特定步骤中,所有片段都可以轻松访问其字段并将它们填入。
由于我是Android新手,我想听听专家对使用单例模式而非传递数据之间的建议,例如实现接口(听说很复杂且难以维护)。任何建议都将是有帮助的。
我在ViewPager
中有5个片段,用来逐步填充业务对象的多个字段,每一步都会设置其中一些字段。我阅读了许多关于片段之间通信的文章,但并不喜欢其他人提倡的方式,所以在思考如何在我的情况下处理这个问题后,我最终开始考虑使用单例模式对象,在特定步骤中,所有片段都可以轻松访问其字段并将它们填入。
由于我是Android新手,我想听听专家对使用单例模式而非传递数据之间的建议,例如实现接口(听说很复杂且难以维护)。任何建议都将是有帮助的。
虽然单例模式看起来易于实现和理解,但这并不是实现所需功能的最佳方式。其中一个原因是您的模型对象或业务对象存在于活动上下文之外,这可能会导致难以找到的错误。例如,在系统创建多个活动类实例且都保留对您的单例的引用的情况下。看看您如何追踪对象?
我会做的是
Parcelable
,开始时你会讨厌它,但一旦习惯了,它就会成为你模型的好帮手。设置你的片段参数,如果已经实例化则获取参数并添加你的模型。这里有一个示例:
如果片段还未激活:
Bundle args = new Bundle();
args.putParcable("businessObject", yourBusinessObjectThatIsParcable);
yourFragment.setArguments(args);
否则:
yourFragment.getArguments().putParcelable("businessObject", yourBusinessObjectThatIsParcable);
在你的片段中,例如在onCreateView方法中,通过如下方式获取你的模型对象:MyParcableObject mpo = (MyParcableObject)getArguments().getParcelable("businessObject")
,然后使用它来设置任何你想要的数据。
当你在按钮单击或onPause方法中完成编辑对象时,更新你的片段参数同样通过getArguments().putParcelable("businessObject", mpo);
在你的最后一页或最后一个片段中,你可以将你的对象传递给你的活动,这里是如何实现的。
onSaveInstanceState()
中保存它,并在onCreate()
中恢复它。ViewPager中的所有片段都可以通过调用getActivity()
获取对父Activity的引用。或者,如果您的ViewPager在一个Fragment中,则所有片段都可以通过调用getParentFragment()
来访问父Fragment。然后,您可以将结果强制转换为适当的类(最好是接口),并进行方法调用以传递数据。在父Activity/Fragment中跟踪业务数据。这样,您就不需要全局单例了。
public class MyParentFragment extends Fragment {
private String mPageOneData;
private int mPageTwoData;
private List<Date> mPageThreeData;
public void setPageOneData(String data) {
mPageOneData = data;
}
...
}
public class PageOneFragment extends Fragment {
private void sendDataToParent(String data) {
Fragment f = getParentFragment();
if (f != null && f instanceof MyParentFragment) {
MyParentFragment parent = (MyParentFragment) f;
f.setPageOneData(data);
}
}
}
onSaveInstanceState
,但是它将有些难以维护(正如您所说,您是Android的新手)。您可以使用单例来进行操作
SharefPreference
(最好)- 如果您想要使用单个值。让你的对象可被打包,然后使用 bundle 将其传递给其他片段。例如:bundle.putParcelable(obj) Parcelable 很高效和快速。
这应该会激励你。
public interface Updateable {
public void update();
}
在需要更新的fragment中实现此接口,并编写代码以在update
方法内通知适配器:
public class FragmentOne extends Fragment implements MainActivity.Updateable {
...
@Override
public void update() {
// YOUR CODE TO UPDATE HERE, FOR EXAMPLE, HERE I'M UPDATING THE ADAPTER
if ( adapter != null ) {
adapter.notifyDataSetChanged();
} else {
Log.d("LOG_TAG", "null");
}
}
...
}
当片段首次加载时,从MainActivity调用update
方法。您可以通过覆盖PagerAdapter
中的getItemPosition
方法来实现此操作,如下所示:
@Override
public int getItemPosition(Object object) {
if ( object != null && object instanceof FragmentOne ) {
FragmentOne f = (FragmentOne) object;
f.update();
}
return super.getItemPosition(object);
}
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int previousState;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (previousState == ViewPager.SCROLL_STATE_SETTLING && state == ViewPager.SCROLL_STATE_IDLE) {
if ( viewPagerAdapter.getItem(viewpager.getCurrentItem()) instanceof Pictures ) {
Log.d("LOG_TAG", "New Position=" + viewpager.getCurrentItem());
viewPagerAdapter.notifyDataSetChanged();
}
}
previousState = state;
}
});