2013-10-12 123 views
7

我知道的一种方法是通过activity.We可以将数据从片段发送到活动并将活动发送到片段有没有其他方法。如何将数据从一个片段传输到另一个片段android

+0

使用接口与主机活动进行通信然后传输数据t从活动 – Raghunandan

+0

^的片段不,不这样做.. 看到这个.. [http://stackoverflow.com/questions/13733304/ callback-a-a-a-a -fragment](http://stackoverflow.com/questions/13733304/callback-to-a-fragment-from-a-dialogfragment) – Zyoo

+0

@Zyoo为什么会这样? – Raghunandan

回答

4

从文档

引用通常你会想要一个片段与另一个通信,例如改变基于用户事件的内容。 所有片段到片段的通信都是通过关联的活动完成的。两个碎片不应该直接通信。

我建议您按照文档的方法,我还没有尝试过任何其他替代

对于chekc的文档的详细信息和示例中的以下链接

http://developer.android.com/training/basics/fragments/communicating.html

+0

如果我使用'setRetainInstance(true)',该怎么办?它是否仍然需要先传递给活动? – Zyoo

+0

是的。检查文档http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean) – Raghunandan

14

要传递数据从一个片段到另一个Bundle将有所帮助。

LifeShapeDetailsFragment fragment = new LifeShapeDetailsFragment(); // object of next fragment 
Bundle bundle = new Bundle(); 
bundle.putInt("position", id); 
fragment.setArguments(bundle); 

然后push/call next Fragments.

和代码下一个片段:

Bundle bundle = this.getArguments(); 
int myInt = bundle.getInt("position", 0); 
+2

根据原始的android开发者文档,这种方法是错误的。我们应该使用活动在两个片段之间进行通信。这里是链接:http://developer.android.com/intl/vi/training/basics/fragments/communicating.html – salih

0

允许片段通过使用活动作为其中介是一种常见的最佳实践使用片段时相互通信。请访问http://developer.android.com/guide/components/fragments.html以了解有关此重要模式的更多详情。无论何时您需要与另一个片段进行交互,您应该始终在片段的活动中使用一种方法,而不是直接访问其他片段。从另一个片段访问片段唯一有意义的是当你知道你不需要在另一个活动中重用你的片段时。假设您将重用它们而不是将它们硬编码到彼此,您几乎总是应该编写片段。

4

有两种方法我会考虑可行的:

一个 .Communicate与你所属的活动和转发消息通过到,拥有活动的其他片段,对细节可以诠释他的官方Android文档在这里找到:

http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

报价:

在某些情况下,您可能需要使用片段与 活动共享事件。一个好的方法是在片段内定义一个回调接口 ,并要求主机活动实现它。 当活动通过接口收到回调时,它可以根据需要与布局中的其他片段共享信息。

通信接口可以是这个样子:

public interface IActionListener{ 

    //You can also add parameters to pass along etc 
    public void doSomething(); 
} 

片段会是这个样子:

public class MyFragment extends Fragment{ 

private WeakReference<IActionListener> actionCallback; 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     try { 
      // This makes sure that the container activity has implemented 
      // the callback interface. If not, it throws an exception 
      actionCallback = new WeakReference<IActionListener>((IActionListener) activity); 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() + " must implement IActionListener."); 
     } 
    } 
} 

我在这里使用的WeakReference但是这真的取决于你。现在可以使用actionCallback与拥有的活动进行通信并调用IActionListener中定义的方法。

所属的活动应该是这样的:

public class MyActivity extends ActionBarActivity implements IActionListener { 

public void doSomething(){ //Here you can forward information to other fragments } 

} 

。现在至于第二种方法 - 您可以使用接口将片段直接相互通信 - 这样您就不必知道与您通话的片段的确切类别,从而确保了松耦合。

设置如下:您有两个片段(或更多)和一个活动(启动第二个片段)。我们有一个界面,可以让Fragment 2在完成任务后向Fragment 1发送响应。为了简便起见,我们只是重新使用我A.

这里定义的接口是我们的片段1:

public class FragmentOne extends Fragment implements IActionListener { 

public void doSomething() {//The response from Fragment 2 will be processed here} 

} 

使用要求它拥有活动在A.片段1所描述的方法启动Fragment 2.然而,Activity将沿着Fragment 1作为参数传递给Fragment 2,因此Fragment 2可以稍后间接访问Fragment 1并发送回复。让我们来看看活动如何PREPS片段2:

public class MyActivity extends ActionBarActivity { 

    // The number is pretty random, we just need a request code to identify our request later 
    public final int REQUEST_CODE = 10; 
    //We use this to identify a fragment by tag 
    public final String FRAGMENT_TAG = "MyFragmentTag"; 

     @Override 
     public void onStartFragmentTwo() { 
      FragmentManager manager = getSupportFragmentManager(); 
      FragmentTransaction transaction = manager.beginTransaction(); 

        // The requesting fragment (you must have originally added Fragment 1 using 
        //this Tag !) 
      Fragment requester = manager.findFragmentByTag(FRAGMENT_TAG); 
        // Prepare the target fragment 
      Fragment target = new FragmentTwo(); 
        //Here we set the Fragment 1 as the target fragment of Fragment 2's  
        //communication endeavors 
      target.getSelf().setTargetFragment(requester, REQUEST_CODE); 

        // Hide the requesting fragment, so we can go fullscreen on the target 
      transaction.hide(requester); 
      transaction.add(R.id.fragment_container, target.getSelf(), FRAGMENT_TAG); 
      transaction.addToBackStack(null); 

      transaction.commit(); 
     } 
    } 

提示:我使用的是支持的框架,因此,如果您> Android 3.0的,你可以简单地使用,而不是ActionBarActivity FragmentActivity独自去开发。

现在正在启动FragmentTwo,让我们来看看FragmentTwo如何与FragmentOne通信:

public class FragmentTwo extends Fragment { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     if(savedInstanceState != null){ 
      // Restore our target fragment that we previously saved in onSaveInstanceState 
      setTargetFragment(getActivity().getSupportFragmentManager().getFragment(savedInstanceState, TAG), 
        MyActivity.REQUEST_CODE);   
     } 

     return super.onCreateView(inflater, container, savedInstanceState); 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     // Retain our callback fragment, the TAG is just a key by which we later access the fragment 
     getActivity().getSupportFragmentManager().putFragment(outState, TAG, getTargetFragment()); 
    } 

    public void onSave(){ 
     //This gets called, when the fragment has done all its work and is ready to send the reply to Fragment 1 
     IActionListener callback = (IActionListener) getTargetFragment(); 
     callback.doSomething(); 
    } 

} 

现在DoSomething的的片段1()的执行将被调用。

+0

我认为你的第一个代码片段中存在代码错误。你可以在一个地方调用你的WeakReference“ActionListener”,在另一个地方调用“ActionCallback”。你能检查一下吗? –

+0

@ParthShah哦谢谢!把它写成我的头顶,并没有仔细检查变量名称 - 再次感谢你,我改正了它 – AgentKnopf

+0

尽管如此,答案很棒,有很多很棒的例子!做得好! –

2

这里是解决方案,

遵循以下步骤:

1 2.implements使用这个接口

for.e.g 
    public class OrderDetail extends ActionBarActivity implements TitleChangeListener 

3您的活动创造这样的

接口.in此活动创建于onUpdateTitle()

 public void onUpdateTitle(String title) 
     { 
     //here orderCompletedDetail is the object second fragment name ,In which fragement I want send data. 

     orderCompletedDetail.setTitle(title); 
     } 

4.现在,在Fragment中写一些代码。

  public class OrderPendingDetail extends Fragment 
      { 
      private View rootView; 
      private Context context; 
      private OrderDetail orderDetail; 
      @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
      { 
      rootView = inflater.inflate(R.layout.order_pending_detail, container, false); 
      context = rootView.getContext(); 

      //here OrderDetail is the name of ActionBarActivity 
      orderDetail = (OrderDetail) context; 

     //here pass some text to second Fragment using button ClickListener 
      but_updateOrder.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) 
       { 
       // here call to Activity onUpdateTitle() 
       orderDetail.onUpdateTitle("bridal"); 
       } 
     }); 
     return rootView; 
     } 
     } 

5.write一些代码在第二片段的setTitle()

  public void setTitle(String title) 
      { 
      TextView orderCompeted_name=(TextView)rootView.findViewById(R.id.textView_orderCompeted_name); 
      orderCompeted_name.setText(title); 
      //here you see the "bridal" value for TextView 
      } 

在当你点击那个时候它示出了在第二片段值片段一个按钮该溶液中。 我希望这会对你有所帮助。

相关问题