在片段和活动之间进行通信 - 最佳实践

Kri*_*lsh 55 android communication android-fragments android-activity

这个问题主要是征求关于处理我的应用程序的最佳方式的意见.我有三个片段由一个活动处理.片段A有一个可点击元素照片,片段B有4个可点击元素按钮.另一个片段只显示单击照片时的详细信息.我正在使用ActionBarSherlock.

屏幕截图

前进和后退按钮需要分别将照片更改为下一个或上一个姿势.我可以将照片和按钮保持在相同的片段中,但是想要将它们分开,以防我想在平板电脑中重新排列它们.

我需要一些建议 - 我应该将碎片A和B结​​合起来吗?如果没有,我将需要弄清楚如何为3个可点击项目实现一个界面.

我考虑过使用Roboguice,但我已经在使用SherlockFragmentActivity进行扩展,所以这是不行的.我看到提到Otto,但我没有看到关于如何包含在项目中的好教程.您认为最佳设计实践应该是什么?

我还需要帮助找出如何在片段和活动之间进行通信.我想在应用程序中保留一些"全局"数据,比如姿势ID.除了股票开发者的信息之外,我还能看到一些示例代码吗?这不是那么有用.

顺便说一下,我已经在SQLite数据库中存储了每个姿势的所有信息.这很容易.

Een*_*ble 76

在您的活动和片段之间进行通信的最简单方法是使用接口.这个想法基本上是在给定片段A中定义一个接口,让活动实现该接口.

一旦它实现了该接口,您可以在它覆盖的方法中执行任何您想要的操作.

界面的另一个重要部分是您必须从片段中调用抽象方法并记住将其强制转换为您的活动.如果没有正确完成,它应该捕获ClassCastException.

Simple Developer Blog上有一个关于如何做到这一点的好教程.

我希望这对你有所帮助!

  • 这就是我最后做的事情.谢谢. (2认同)
  • 接口很好.但是对于更松散的耦合,请使用广播听众. (2认同)

Boo*_*ger 23

建议的片段之间通信方法是使用由主Activity管理的回调\侦听器.

我认为此页面上的代码非常清晰:http: //developer.android.com/training/basics/fragments/communicating.html

您还可以参考IO 2012 Schedule应用程序,该应用程序旨在成为事实上的参考应用程序.可在此处找到:http: //code.google.com/p/iosched/

此外,这是一个提供良好信息的SO问题: 如何在片段之间传递数据


小智 11

它是通过回调接口实现的:首先我们要创建一个接口:

public interface UpdateFrag {
     void updatefrag();
}
Run Code Online (Sandbox Code Playgroud)

在活动中执行以下代码:

UpdateFrag updatfrag ;

public void updateApi(UpdateFrag listener) {
        updatfrag = listener;
}
Run Code Online (Sandbox Code Playgroud)

来自回调必须在活动中触发的事件:

updatfrag.updatefrag();
Run Code Online (Sandbox Code Playgroud)

在Fragment中,CreateView中的接口执行以下代码:

 ((Home)getActivity()).updateApi(new UpdateFrag() {
        @Override
        public void updatefrag() {
              .....your stuff......
        }
 });
Run Code Online (Sandbox Code Playgroud)


xar*_*g89 8

anActivityFragments之间的通信,有几种选择,但是经过大量阅读和许多经验,我发现可以通过这种方式恢复:

  • Activity想与孩子交流Fragment=> 只需在您的Fragment类中编写公共方法,然后Activity调用它们
  • Fragment想与父母沟通Activity=>这需要多一点的工作,因为Android官方链接https://developer.android.com/training/basics/fragments/communicating表明,这将是一个伟大的想法来定义interface该将由 实施Activity,并且将为任何Activity想要与之通信的人建立合同Fragment。例如,如果您有FragmentA, 想要与任何activity包含它的人进行通信,那么定义FragmentAInterface将定义可以FragmentA调用activities决定使用它的方法的 。
  • AFragment想与其他人交流Fragment=> 在这种情况下,您会遇到最“复杂”的情况。因为你可能需要从FragmentA数据传递到FragmentB,反之亦然,这可能会导致我们定义2个接口,FragmentAInterface这将通过实施FragmentBFragmentAInterface将被执行FragmentA。这将开始使事情变得混乱。并想象一下,如果您有更多Fragment的地方,甚至父母也activity想与他们交流。那么,这种情况下是一个完美的时刻,以建立一个共享ViewModelactivity,它的fragment秒。更多信息在这里https://developer.android.com/topic/libraries/architecture/viewmodel。基本上,您需要定义一个SharedViewModel类,其中包含您想要在activity和之间共享的所有数据,这些数据fragments将需要在它们之间进行数据通信。

这种ViewModel情况最终使事情变得非常简单,因为您不必添加额外的逻辑来使代码中的事情变得肮脏和混乱。此外,它还允许您将数据的收集(通过调用 SQLite 数据库或 API)与Controller(activitiesfragments)分开。


Ars*_*rst 5

我做了一个注释库,可以为你做演员。看一下这个。 https://github.com/zeroarst/callbackfragment/

@CallbackFragment
public class MyFragment extends Fragment {

    @Callback
    interface FragmentCallback {
       void onClickButton(MyFragment fragment);
    }    
    private FragmentCallback mCallback;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt1
                mCallback.onClickButton(this);
                break;
            case R.id.bt2
                // Because we give mandatory = false so this might be null if not implemented by the host.
                if (mCallbackNotForce != null)
                mCallbackNotForce.onClickButton(this);
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后它生成片段的子类。并将其添加到 FragmentManager。

public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction()
            .add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), "MY_FRAGM")
            .commit();
    }

    Toast mToast;

    @Override
    public void onClickButton(MyFragment fragment) {
        if (mToast != null)
            mToast.cancel();
        mToast = Toast.makeText(this, "Callback from " + fragment.getTag(), Toast.LENGTH_SHORT);
        mToast.show();
    }
}
Run Code Online (Sandbox Code Playgroud)