【问题标题】:How to manage data passing?如何管理数据传递?
【发布时间】:2017-01-25 09:05:30
【问题描述】:

我目前正在为我的应用程序和设置设计的模块 1 工作,我也想申请其他模块。

我在模块 1 中有以下元素

  1. MainActivity -> 3 个片段 [A, B, C]
  2. 所有 3 个片段都包含 -> ViewPager
  3. 每个 ViewPager 都有 -> 5 个片段 [p, q, r, s, t]
  4. 所有 ViewPager 片段都是一种输入表单,希望从 ViewPager 的片段 1 到 2 到 3 到 5 共享数据。在片段 5 上,启用保存数据的 SAVE 按钮。 (假设片段 1-5 表示 p-t)
  5. 另一部分是 Fragment 1 或 A 类似于容器,其中包含 ViewPager 代码以加载 5 个子片段并从顺序片段中获取数据并进一步传递。

我的问题是,

这似乎非常想这样做是正确的方法还是我应该改变这个设计模式?而且,如果这种设计方法是正确的,那么我应该如何管理数据传递?

【问题讨论】:

  • 三个主要片段有什么不同?他们只是更新不同的对象吗?您在哪里显示最终更新的数据?还是您只是存储它并继续显示输入表单?此外,第 5 项也不是很清楚。片段A是否有与1-4中描述的场景不同的特殊情况?
  • 将按 Q 回答 Q。3 个片段是 3 个不同的子流。所有这些都是独立的,但可以使用从早期片段中保存的 SQLIte 获取数据。只需收集数据并发送到 API 和 SQLite。 Fragment 的输入字段很少,SAVE 按钮和 1-4 仅具有 SWIPE 功能来移动下一个屏幕。

标签: android android-fragments android-viewpager android-pageradapter fragmentstatepageradapter


【解决方案1】:

请记住,您将有不同的方法来做到这一点,没有一种方法是正确的,只是更容易或更干净。 所以,如果我是你,我会尝试分离域对象,并有一个数据模型和只处理视图部分的视图。 对我来说,最好的方法是遵循 MVVM 模式,它可以让您进行大量控制,您可以在 Google android 数据绑定库文档中了解它。

另一种方法是破解它,比方说,拥有一个所有视图都可以访问的 Singleton WorkFlowManager,并在其中包含所有数据和业务逻辑。 这样,Any Fragment/Activity 可以检查是否设置了所有表单字段并使“保存”按钮可见(例如)。 如果您想使用事件更新视图,您可以在 Manager 上创建自定义 eventListeners,一旦最后一个字段被填充,就会触发 FormFilledEvent(或类似事件)并让 Fragment 注册该事件以侦听它,并制作 Button可见。

这是一个用例,但你可以有多个

编码愉快 ;)

【讨论】:

    【解决方案2】:

    这似乎非常想这样做是正确的方法还是 我应该改变这个设计模式

    对我来说,这确实有点过于复杂的设计。我宁愿将ViewPager 的所有 5 个片段保留为一个带有保存 FAB/按钮的表单,以避免将数据从主片段传递到每个子片段。但是,在您描述的情况下,这可能会导致表单很长,或者如果字段依赖于以前的字段,则检查过多。

    如果这种设计方法是正确的,那么我应该如何管理数据 路过?

    对于每个主要Fragment,我将使用一个实现Parcelable 的对象,用于从主片段上的数据库加载的整个子流,然后一次传递给子片段填充相应的字段.最后一个子片段负责将更新后的对象保存到数据库中,或者只是将其传递回主片段进行保存

    更新:

    我没有测试过这段代码,但这是我将数据从主片段传递到子片段的一种方法:

    MainFragment.java

    public class MainFragment extends Fragment 
    {    
        private MyObj myObj;
        private SubFragment currentFragment;
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
        {
            final View view = inflater.inflate(R.layout.fragment, parent, false);
            final ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
    
            myObj = db.loadObject();
            pager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
    
            return view;
        }
    
        public static class MyPagerAdapter extends FragmentPagerAdapter
        {
    
            MyPagerAdapter(FragmentManager manager)
            {
                super(manager);
            }
    
            @Override
            public Fragment getItem(int position)
            {
                if(currentFragment != null) myObj = currentFragment.getMyObj();
                switch(position)
                {
                   case 4: 
                       currentFragment = FragmentT.getInstance(myObj);
                       break;
                   case 3: 
                       currentFragment =  FragmentS.getInstance(myObj);
                       break;
                   case 2: 
                       currentFragment =  FragmentR.getInstance(myObj);
                       break;
                   case 1: 
                       currentFragment = FragmentQ.getInstance(myObj);
                       break;
                   case 0: 
                   default: 
                       currentFragment = FragmentP.getInstance(myObj);
                }
                return currentFragmnet;
             }
    
             @Override
             public int getCount()
             {
                return 5;
             }
    
            @Override
            public CharSequence getPageTitle(int position)
            {
                return titles[position]; 
            }
        }
    }
    

    SubFragment.java

    public class SubFragment extends Fragment
    {
        protected static final String ARGS = "args";
    
        protected MyObj myObj;
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
    
            final Bundle args = getArguments();
            if (args != null)
            {
                myObj = args.getParcelable(ARGS);
            }
        }
    
        public MyObj getMyObj()
        {
            return myObj;
        }
    }
    

    FragmentP.java

    public class FragmentP extends SubFragment
    {        
        public static FragmentP getInstance(MyObj myObj)
        {
            final FragmentP fragment = new FragmentP();
            final Bundle args = new Bundle();
            args.putParcelable(ARGS, myObj);
            fragment.setArguments(args);
            return fragment;
        }
    
        ...
    }
    

    【讨论】:

    • 不,但是您将如何设法将 SWIPE 上的数据从片段 1 传递到另一个片段。我的意思是您将如何管理子片段中的页面更改侦听器。
    • @VVB 我已经用一些将数据传递给子片段的代码更新了我的答案
    【解决方案3】:

    这可以使用观察者设计模式来解决。使您的模型可观察,并将所有要更新的 ui 组件注册为观察者。我会推荐 RXjava 来解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-25
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      • 2014-12-20
      • 2021-06-27
      • 2012-01-17
      • 1970-01-01
      相关资源
      最近更新 更多