在开始之前,我已经看过诸如以下的问题:
Passing data between fragments: screen overlap How to pass values between Fragments
以及Android文档:
http://developer.android.com/training/basics/fragments/communicating.html
以及这篇文章:
http://manishkpr.webheavens.com/android-passing-data-between-fragments/
尽管上面提到的所有情况都与我的相似,但它并不完全相同。我在这里遵循了一个很好的教程(我的部分代码基于这篇文章):
http://www.androidhive.info/2013/10/android-tab-layout-with-swipeable-views-1/
我有以下文件:
RegisterActivity.java
NonSwipeableViewPager.java
ScreenSliderAdapter.java
RegisterOneFragment.java
RegisterTwoFragment.java
以下布局:
activity_register.xml
fragment_register_one.xml
fragment_register_two.xml
我想要实现的是将Serializable对象从RegisterFragmentOne传递给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上的按钮时,数据将被发送到服务器(并通过JSON返回一些验证)。如果返回的数据有效,则应用程序应转到下一个片段,即RegistrationTwoFragment。
我对如何在片段之间传递对象感到困惑,因为我的片段是使用适配器创建的。然后将该适配器附加到我的Activity。
任何人都可以帮我吗? THX
修改1:
我试图像这样制作一个快捷方式(遗憾的是不起作用):
在我创建的RegisterActivity中:
public Registration regData;
并在RegisterOneFragment中:
/* PLACED ON POST EXECUTE */
((RegisterActivity)getActivity()).regData = regData;
最后在RegisterTwoFragment中调用它
Registration regData;
regData = ((RegisterActivity) getActivity()).regData;
抛出nullPointerExceptions
修改2
为了清楚起见,RegisterActivty包含多个片段。用户可以在片段之间导航的唯一方法是单击按钮。活动没有标签栏。
答案 0 :(得分:7)
通过将Serializable实现到自定义对象,可以轻松共享对象。我写了一篇关于这个here的教程。
来自片段一:
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());
答案 1 :(得分:3)
我通常会在包含活动中使用类似于此的setter或方法。
因此,如果我理解正确,您希望用户访问RegistrationOneFragment
,然后在完成后,使用此数据进行验证,如果有效,则将其传递给RegistrationTwoFragment
并将用户移至这个Fragment
。
您是否可以在validateJson(regData)
方法中调用onEmailRegistered
来处理活动中的验证,如果成功,则将交易提交到RegistrationTwoFragment
。
然后您需要的只是活动或片段中的getter和setter,以便在活动中说getRegistrationOneData()
或在片段中setData(Registration args)
,如上面的示例所示。
我不知道如何将args直接传递给Fragment。
答案 2 :(得分:1)
我找到了一个问题的解决方案,我肯定不是正确的方法......
所以在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中(或在我想要接收Object的Fragment中):
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_register_two, container, false);
regData = ((RegisterActivity) getActivity()).getRegistrationData();
...
答案 3 :(得分:0)
我曾经用Pacelable或Serializable设置对象进行传输,但每当我向对象(模型)添加其他变量时,我必须将其全部注册。这太不方便了。
在活动或片段之间传输对象非常容易。
将您的数据对象放入您的活动或片段中的KimchiDataCache实例。
letterbox
在您添加的片段活动中获取数据对象。
User userItem = new User(1, "KimKevin"); // Sample Model
KimchiDataCache.getInstance().put(userItem);
// add your activity or fragment