Android:在碎片之间传递对象

在我开始之前,我已经看过如下问题:

在片段之间传递数据:屏幕重叠 如何在片段之间传递值

以及Android文档:

http://developer.android.com/training/basics/fragments/communicating.html

以及这篇文章:

Android Passing Data Between Fragments

虽然上面提到的所有情况与我所说的相似,但并不完全相同。 我在这里跟着一个很好的教程(我的代码的一部分是基于这篇文章):

Android Tab Layout with Swipeable Views

我有以下文件:

RegisterActivity.java
NonSwipeableViewPager.java
ScreenSliderAdapter.java
RegisterOneFragment.java
RegisterTwoFragment.java

以下布局:

activity_register.xml
fragment_register_one.xml
fragment_register_two.xml

我想实现的是从RegisterFragmentOne传递一个Serializable对象到RegisterFragmentTwo。

到目前为止,这是我所做的(有些代码被省略):

RegisterActivity.java

public class RegisterActivity extends FragmentActivity implements RegisterOneFragment.OnEmailRegisteredListener{ public static NonSwipeableViewPager viewPager; private ScreenSliderAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); // Initilization mAdapter = new ScreenSliderAdapter(getSupportFragmentManager()); viewPager = (NonSwipeableViewPager) findViewById(R.id.pager); viewPager.setAdapter(mAdapter); } public void onEmailRegistered(int position, Registration regData){ Bundle args = new Bundle(); args.putSerializable("regData", regData); viewPager.setCurrentItem(position, true); } } 

ScreenSliderAdapter.java

 public class ScreenSliderAdapter extends FragmentPagerAdapter{ public ScreenSliderAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int index) { switch (index) { case 0: return new RegisterOneFragment(); case 1: return new RegisterTwoFragment(); case 2: return new RegisterThreeFragment(); } return null; } @Override public int getCount() { return 3; } } 

NonSwipeableViewPager.java (扩展ViewPager类,并覆盖以下内容)

 @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { // Never allow swiping to switch between pages return false; } @Override public boolean onTouchEvent(MotionEvent event) { // Never allow swiping to switch between pages return false; } 

RegisterOneFragment.java

 public class RegisterOneFragment extends Fragment { OnEmailRegisteredListener mCallBack; public interface OnEmailRegisteredListener { /** Called by RegisterOneFragment when an email is registered */ public void onEmailRegistered(int position, Registration regData); } public void onAttach(Activity activity){ super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception. try { mCallBack = (OnEmailRegisteredListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnEmailRegisteredListener"); } } ... And some to execute some HTTP request via separate thread... } 

我试图完成的是,当用户按下RegisterOneFragment上的button时,数据将被发送到服务器(并返回一些通过JSONvalidation)。 如果返回的数据是有效的,应用程序应该去下一个是RegistrationTwoFragment的片段。

我有一些混淆如何传递片段之间的对象,因为我的碎片是使用适配器创build的。 然后,该适配器被附加到我的活动。

谁能帮我这个? 谢谢

编辑1:

我试图做一个快捷方式(不幸的是不工作),如下所示:

在我创build的RegisterActivity中:

 public Registration regData; 

并在RegisterOneFragment:

 /* PLACED ON POST EXECUTE */ ((RegisterActivity)getActivity()).regData = regData; 

最后在Re​​gisterTwoFragment中调用它

 Registration regData; regData = ((RegisterActivity) getActivity()).regData; 

它抛出一个nullPointerExceptions

编辑2

只是要清楚,RegisterActivty包含多个片段。 用户可以在片段之间导航的唯一方法是单击button。 该活动没有标签栏。

Solutions Collecting From Web of "Android:在碎片之间传递对象"

我通常会在包含的活动中使用与此类似的setter或方法。

所以,如果我理解正确,你希望用户访问RegistrationOneFragment ,然后完成后,使用这些数据,validation它,如果有效,将它传递到RegistrationTwoFragment并将用户移动到这个Fragment

你可以简单地在你的onEmailRegistered方法中调用validateJson(regData)来处理你的活动中的validation,如果成功的话,将一个事务提交给RegistrationTwoFragment

然后,只需要在活动或片段中的getter和setter来说明片段中的getRegistrationOneData()或片段中的setData(Registration args) ,如上面的示例所示。

我不知道有什么办法可以直接将parameter passing给片段。

通过将Serializable实现到自定义对象很容易。 我在这里写了一篇关于这个的教程。

从片段一:

 android.support.v4.app.FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); OfficeCategoryFragment frag = new OfficeCategoryFragment(); Bundle bundles = new Bundle(); Division aDivision = divisionList.get(position); // ensure your object has not null if (aDivision != null) { bundles.putSerializable("aDivision", aDivision); Log.e("aDivision", "is valid"); } else { Log.e("aDivision", "is null"); } frag.setArguments(bundles); ft.replace(android.R.id.content, frag); ft.addToBackStack(null); ft.commit(); 

在片段二:

 Bundle bundle = getArguments(); Division division= (Division) bundle.getSerializable("aDivision"); Log.e("division TEST", "" + division.getName()); 

我find了解决我的问题,我相信不是正确的方法来做到这一点…

所以在RegisterActivity.java我添加+修改了以下几行(thx到@sturrockad):

 public Registration getRegistrationData(){ return this.regData; } public void onEmailRegistered(int position, Registration regData){ this.regData = regData; viewPager.setCurrentItem(position, true); } 

然后在RegisterTwoFragments.java(或我想要接收对象的片段):

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_register_two, container, false); regData = ((RegisterActivity) getActivity()).getRegistrationData(); ... 

我用Pacelable或Serializable来设置对象来传输,但每当我添加其他variables对象(模型),我必须注册这一切。 这太不方便了。

在活动或片段之间传输对象是非常容易的。

Android数据caching

  1. 把你的数据对象放到你的activity或fragment中的KimchiDataCache实例中。

     User userItem = new User(1, "KimKevin"); // Sample Model KimchiDataCache.getInstance().put(userItem); // add your activity or fragment 
  2. 获取你的数据对象在你添加的片段的活动中。

     public class MainFragment extends Fragment{ private User userItem; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); userItem = KimchiDataCache.getInstance().get(User.class); }