在ViewPager中的多个片段之间的通信对象

我在ViewPager有5个片段用于逐步填充具有多个字段的业务对象,每个步骤中的一些字段将被设置。 我已经阅读了很多关于片段之间的交stream的文章,但是我不太喜欢别人喜欢的方式,所以在思考如何在我的情况下这样做之后,最后我开始考虑使用单件模型对象,所有片段都可以很容易地访问到其领域并填写具体步骤。

因为我是新来的android我想听到专家有关使用单例,而不是在片段之间传递数据,如实现的接口(这似乎是如此复杂,难以维护)。 任何build议将是有益的。

Solutions Collecting From Web of "在ViewPager中的多个片段之间的通信对象"

虽然单身方法似乎很容易实现和理解,但它不是最好的方式来实现你所需要的。 一个原因是你的模型对象或者你称之为业务对象的活动不在你的活动的上下文之中,这可能很难find错误。 例如,当您的活动类的多个实例由系统创build并且都保持引用您的单例时。 看看你如何失去你的对象的轨道?

我会做的是

  1. 让我的模型对象实现Parcelable你会在开始时讨厌它,但一旦你习惯了它,它将成为你模型的最好的朋友
  2. 由于您的模型现在可以分类,所以您可以轻松地在片段,活动之间传递它,甚至可以将其保存在共享首选项中。 这里需要注意的一件事情是,当你在片段或者活动之间传递你的parcelable ,它就像是按值传递,也就是每次创build新实例。
  3. 设置您的片段的参数,或者如果它已经实例化,然后获取参数并添加您的模型。 这里是一个例子:如果一个片段还没有被激活,

    Bundle args = new Bundle(); args.putParcable("businessObject", yourBusinessObjectThatIsParcable); yourFragment.setArguments(args);

    否则: yourFragment.getArguments().putParcelable("businessObject", yourBusinessObjectThatIsParcable);

  4. 在你的片段或许在onCreateView方法获取你的模型对象像这样MyParcableObject mpo = (MyParcableObject)getArguments().getParcelable("businessObject")并使用它设置任何你想要的数据。

  5. 当你完成编辑你的对象的button点击或onPause方法更新你的片段的参数相同的方式getArguments().putParcelable("businessObject", mpo);

  6. 在你的最后一页或最后一个片段中,你可以将你的对象传递给你的活动,下面是如何做到这一点

尽pipe看起来很麻烦,但是您需要习惯于作为一名android开发者。 当你的模型实现parcelable时,你可以获得更多的控制parcelable

另一种做你需要的是通过委托模式,但它主要用于callback,即使你也可以传递对象。

我不会推荐一个全球性的单身人士。 主要有两个原因:

  1. 根据定义,单身人士将您的应用程序限制为主要业务对象的单个实例。 如果你(或者devise师,或者你的老板的老板的老板)决定同时拥有多个这样的ViewPage,你将不得不改变你的架构。
  2. “Android的思维方式”是希望你的用户可以把你的应用程序在后台,并使用其他应用程序,然后才能返回到您的应用程序。 如果系统决定在后台终止你的应用程序,那么你的单例内存对象将被销毁,你的用户将失去所有的进度。 正确的Android保存状态方法是将状态保存在Activity或Fragment中,并将其妥善保存在onSaveInstanceState() ,并将其恢复到onCreate()

ViewPager中的所有片段都可以通过调用getActivity()来获得父Activity的引用。 或者,如果您的ViewPager在一个片段内,那么所有片段都可以通过调用getParentFragment()来访问父片段。 然后,您可以将结果转换为相应的类(或者更好的接口),并进行方法调用来传递数据。 跟踪您的业务数据在父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); } } } 
  1. 你可以将你的数据保存在activity的onSaveInstanceState()事件中,以防进程进入后台。 您可以使用Bundle和getExtras()来恢复onCreate()事件中的数据。

  2. 你可以保存你的数据在应用程序类和数据将仍然存在的情况下,你的过程将进入后台。

我更喜欢第一个选项,因为您不想在应用程序类中弄乱来自不同活动和片段的所有数据。 我希望我能帮助:)

你有结帐EventBus吗?

我不确定这是否是最好的方法,特别是当你的问题太宽泛时,但是只有5个片段会很酷。

希望能帮助到你

我想在你的MainActivity中有一个ViewPager ,而FragmentOne将是视图分页器内的片段之一。 这里MainActivity正在与FragmentOne进行通信以刷新他的适配器。 希望是明确的。

在你的MainActivity中添加这个接口:

 public interface Updateable { public void update(); } 

在需要更新的片段中实现此接口,并编写代码以在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); } 

最后,您必须调用viewPager适配器的notifyDataSetChanged()。 这将强制viewpager的适配器调用getItemPosition方法。

 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; } }); 

在select任何选项之前,请记住用户可以导航或打开任何其他应用程序,以便您丢失了数据。

你可以使用onSaveInstanceState但它会以某种方式难以维护(正如你所说你在android中是新的)。 你可以用singleton去

  • 数据库 – 当你想要存储维护多个logging时使用,但你必须创build一个数据库getter / setter或使用像RushOrm等任何ORM
  • SharefPreference (最好) – 如果你想使用单个值。

在这两种情况下,您都将创build一个单例对象并访问片段中的属性。

使您的对象parcelable,然后使用捆绑传递给其他片段。 即bundle.putParcelable(obj)parcelable是非常有效和快速的。

它应该激励你

http://www.developerphil.com/parcelable-vs-serializable/