如何在片段之间传递数据

Sha*_*aun 75 android android-fragments

我试图在程序中的两个fragmens之间传递数据.它只是一个存储在List中的简单字符串.List在片段A中公开,当用户点击列表项时,我需要它显示在片段B中.内容提供者似乎只支持ID,因此不起作用.有什么建议?

Fed*_*dor 58

我认为片段之间的沟通应该通过活动来完成.片段和活动之间的通信可以这样做:https : //developer.android.com/training/basics/fragments/communicating.html https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

  • 当然.您需要做的是在listview片段上创建一个接口,然后让您的活动实现它.然后使用片段的onAttach方法将其附加到您的活动.然后使用listview片段中的onItemSelected侦听器调用您创建的新侦听器,这将把信息传递回活动.如果您需要更多帮助,可以通过compguru910@gmail.com与我联系 (3认同)

Don*_*ker 21

如果您使用Roboguice,您可以使用Roboguice中的EventManager来传递数据,而无需使用Activity作为接口.这是相当干净的IMO.

如果您不使用Roboguice,您也可以使用Otto作为活动总线:http://square.github.com/otto/

更新20150909:您现在也可以使用绿色机器人事件总线甚至RxJava.取决于您的用例.

  • 如果你喜欢Otto,你可能也会喜欢EventBus,它还提供了线程处理功能.https://github.com/greenrobot/EventBus (9认同)
  • 如果两个片段同时可见,我可以看到事件总线策略有效,但是如果Fragment A(假设它是一个ListFragment)占用整个屏幕并选择一个List项目启动Fragment B,它将如何工作整个屏幕.AFAIK,事件总线模式在onResume/onPause中注册/取消注册每个片段,所以我不确定我是如何应用它的. (4认同)
  • 我全心全意地说出唐恩在这里所说的话.使用总线并解开所有这些东西并停止手动编写监听器和回调.奥托FTW. (3认同)

Lei*_*yba 19

你为什么不使用Bundle.从您的第一个片段开始,以下是如何设置它:

Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt(key, value);
fragment.setArguments(bundle);
Run Code Online (Sandbox Code Playgroud)

然后在第二个片段中,使用以下方法检索数据:

Bundle bundle = this.getArguments();
int myInt = bundle.getInt(key, defaultValue);
Run Code Online (Sandbox Code Playgroud)

Bundle为许多数据类型提供了方法.请参阅http://developer.android.com/reference/android/os/Bundle.html


Jen*_*ohl 17

Fragment 文档:

通常,您会希望一个片段与另一个片段进行通信,例如根据用户事件更改内容.所有Fragment-to-Fragment通信都是通过相关的Activity完成的.两个碎片永远不应该直接通信.

所以我建议您查看文档中的基本片段培训文档.他们非常全面,有一个例子和一个演练指南.


Gen*_*ene 11

所以假设你有Activity AB控制Frag A和Fragment B.在Fragment A里面你需要一个Activity AB可以实现的接口.在示例android代码中,他们有:

private Callbacks mCallbacks = sDummyCallbacks;

/*包含此片段的所有活动必须实现的回调接口.此机制允许活动通知项目选择.*/

public interface Callbacks {
/*Callback for when an item has been selected. */    
      public void onItemSelected(String id);
}

/*A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity. */    
private static Callbacks sDummyCallbacks = new Callbacks() {
    @Override
    public void onItemSelected(String id) {
    }
};
Run Code Online (Sandbox Code Playgroud)

Callback接口放在你的一个Fragment中(比如片段A).我认为这个Callbacks接口的目的就像Frag A中的嵌套类,任何Activity都可以实现.因此,如果片段A是电视,则CallBacks是允许片段A被活动AB使用的电视遥控器(接口).我可能错误的细节,因为我是一个菜鸟但我确实让我的程序在所有屏幕尺寸上完美地工作,这就是我使用的.

所以在Fragment A中,我们有:(我从Android的Sample程序中获取了这个)

@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
//mCallbacks.onItemSelected( PUT YOUR SHIT HERE. int, String, etc.);
//mCallbacks.onItemSelected (Object);
}
Run Code Online (Sandbox Code Playgroud)

在Activity AB中,我们覆盖了onItemSelected方法:

public class AB extends FragmentActivity implements ItemListFragment.Callbacks {
//...
@Override
//public void onItemSelected (CATCH YOUR SHIT HERE) {
//public void onItemSelected (Object obj) {
    public void onItemSelected(String id) {
    //Pass Data to Fragment B. For example:
    Bundle arguments = new Bundle();
    arguments.putString(“FragmentB_package”, id);
    FragmentB fragment = new FragmentB();
    fragment.setArguments(arguments);
    getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit();
    }
Run Code Online (Sandbox Code Playgroud)

所以在Activity AB中,你基本上把所有东西都扔进了Bundle并将它传递给B.如果你不确定如何使用Bundle,那么看看这个类.

我基本上是通过Android提供的示例代码.带有DummyContent的东西.当您制作新的Android应用程序包时,它就是名为MasterDetailFlow的程序包.


Gun*_*han 8

1-第一种方法是定义一个接口

public interface OnMessage{
    void sendMessage(int fragmentId, String message);
}

public interface OnReceive{
    void onReceive(String message);
}
Run Code Online (Sandbox Code Playgroud)

2-在你的活动中实现OnMessage接口

public class MyActivity implements OnMessage {
   ...
   @Override
   public void sendMessage(int fragmentId, String message){
       Fragment fragment = getSupportFragmentManager().findFragmentById(fragmentId);
       ((OnReceive) fragment).sendMessage();
   }
}
Run Code Online (Sandbox Code Playgroud)

3-在您的片段中实现OnReceive接口

public class MyFragment implements OnReceive{
    ...
    @Override
    public void onReceive(String message){
        myTextView.setText("Received message:" + message);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是处理片段之间传递消息的样板版本.

在片段之间处理数据通道的另一种方式是使用事件总线.

1-注册/注销事件总线

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}
Run Code Online (Sandbox Code Playgroud)

2-定义事件类

public class Message{
    public final String message;

    public Message(String message){
        this.message = message;
    }
}
Run Code Online (Sandbox Code Playgroud)

3-在您的应用程序的任何位置发布此事件

EventBus.getDefault().post(new Message("hello world"));
Run Code Online (Sandbox Code Playgroud)

4-订阅该事件以在片段中接收它

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(Message event){
    mytextview.setText(event.message);
}
Run Code Online (Sandbox Code Playgroud)

有关事件总线模式的更多详细信息,用例和示例项目.