首页 文章

Android:在片段之间传递对象

提问于
浏览
8

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

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 .

谁能帮我这个?谢谢

Edit 1:

我试图创建一个快捷方式(不幸的是不起作用),如下所示:

在我创建的RegisterActivity中:

public Registration regData;

在RegisterOneFragment中:

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

最后在RegisterTwoFragment中调用它

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

它抛出一个nullPointerExceptions

Edit 2

为了清楚起见,RegisterActivty包含多个片段 . 用户可以在片段之间导航的唯一方法是单击按钮 . 活动没有标签栏 .

4 回答

  • 1

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

    因此,如果我理解正确,您希望用户访问 RegistrationOneFragment ,那么在完成后,使用此数据,验证它,如果有效,将其传递给 RegistrationTwoFragment 并将用户移动到 Fragment .

    您可以在 onEmailRegistered 方法中调用 validateJson(regData) 来处理活动中的验证,如果成功,则将事务提交到 RegistrationTwoFragment .

    然后你需要的只是你的活动中的getter和setter,或者片段在活动中说 getRegistrationOneData() 或在片段中 setData(Registration args) ,如上面的例子所示 .

    我不知道有什么方法可以将args直接传递给Fragment .

  • 3

    通过将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());
    
  • 0

    我曾经用Pacelable或Serializable设置对象进行传输,但每当我将其他变量添加到对象(模型)时,我必须将其全部注册 . 这太不方便了 .

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

    Android DataCache

    • 将您的数据对象放入活动或片段中的KimchiDataCache实例 .
    User userItem = new User(1, "KimKevin");  // Sample Model
    
    KimchiDataCache.getInstance().put(userItem);
    
    // add your activity or fragment
    
    • 在您添加的片段活动中获取数据对象 .
    public class MainFragment extends Fragment{
         private User userItem;
    
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
    
             userItem = KimchiDataCache.getInstance().get(User.class);
         }
    
  • 7

    我找到了一个问题的解决方案,我肯定不是这样做的正确方法......

    所以在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();
        ...
    

相关问题