如何在碎片之间传递值

我是相当新的使用片段。

我只是试图构build一个简单的示例应用程序使用碎片。 我的情况是,我有两个活动,每个活动中有一个片段。 第一个片段有一个edittext和一个button。 第二个片段有一个textview。 当我在edittext中input一个名字并点击button时,第二个片段中的textview应显示在第一个片段的edittext中input的名称。

我能够将第一个片段的值发送到其活动,然后从该活动发送到第二个活动。 现在我怎么在第二个片段里面使用这个值。

这里是Java代码:::

package com.example.fragmentexample; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class Fragment_1 extends Fragment{ OnFragmentChangedListener mCallback; // Container Activity must implement this interface public interface OnFragmentChangedListener { public void onButtonClicked(String name); } @Override 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 = (OnFragmentChangedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener"); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.fragment_fragment_1, container, false); final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName); Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi); btnSayHi_Fragment.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub String name = edtxtPersonName_Fragment.getText().toString(); FragmentManager fm = getFragmentManager(); Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2); Activity activity = getActivity(); if(activity != null) { Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show(); } if(f2 != null && f2.isInLayout()) { f2.setName(name); } else { mCallback.onButtonClicked(name); } } }); return view; } } 

MainActivity.Java

 package com.example.fragmentexample; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Choreographer.FrameCallback; import android.view.Menu; public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public void onButtonClicked(String name) { // TODO Auto-generated method stub Intent i = new Intent(this, SecondActivity.class); i.putExtra("", name); startActivity(i); } } 

SecondActivity.Java

 package com.example.fragmentexample; import android.app.Activity; import android.os.Bundle; public class SecondActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Bundle b = getIntent().getExtras(); Fragment_2 f2 = new Fragment_2(); f2.setArguments(b); } } 

Fragment_2.Java

 package com.example.fragmentexample; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class Fragment_2 extends Fragment{ View view; TextView txtName; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub view = inflater.inflate(R.layout.fragment_fragment_2, container, false); // Exception at this line String name = getArguments().getString("message"); txtName = (TextView) view.findViewById(R.id.txtViewResult); txtName.setText(name); return view; } @Override public void onAttach(Activity activity) { // TODO Auto-generated method stub super.onAttach(activity); } public void setName(String name) { txtName.setText("Hi " + name); } } 

我得到以下exception:::

 04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main 04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentexample/com.example.fragmentexample.SecondActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.access$500(ActivityThread.java:122) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.os.Handler.dispatchMessage(Handler.java:99) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.os.Looper.loop(Looper.java:132) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.main(ActivityThread.java:4123) 04-16 18:10:24.573: E/AndroidRuntime(713): at java.lang.reflect.Method.invokeNative(Native Method) 04-16 18:10:24.573: E/AndroidRuntime(713): at java.lang.reflect.Method.invoke(Method.java:491) 04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 04-16 18:10:24.573: E/AndroidRuntime(713): at dalvik.system.NativeStart.main(Native Method) 04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment 04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.rInflate(LayoutInflater.java:724) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:479) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:391) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:347) 04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.setContentView(Activity.java:1786) 04-16 18:10:24.573: E/AndroidRuntime(713): at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.performCreate(Activity.java:4397) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779) 04-16 18:10:24.573: E/AndroidRuntime(713): ... 11 more 04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException 04-16 18:10:24.573: E/AndroidRuntime(713): at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.onCreateView(Activity.java:4177) 04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664) 04-16 18:10:24.573: E/AndroidRuntime(713): ... 21 more 

如何从SecondActivity.java中的包获取值到Fragment_2.Java?

步骤1.将数据从片段发送到活动

 Intent intent = new Intent(getActivity().getBaseContext(), TargetActivity.class); intent.putExtra("message", message); getActivity().startActivity(intent); 

步骤2 :在Activity中接收这些数据:

 Intent intent = getIntent(); String message = intent.getStringExtra("message"); 

步骤3 。 从活动发送数据到另一个活动遵循正常的方法

 Intent intent = new Intent(MainActivity.this, TargetActivity.class); intent.putExtra("message", message); startActivity(intent); 

步骤4在活动中接收这些数据

  Intent intent = getIntent(); String message = intent.getStringExtra("message"); 

第5步。从活动你可以意图发送数据片段为:

 Bundle bundle=new Bundle(); bundle.putString("message", "From Activity"); //set Fragmentclass Arguments Fragmentclass fragobj=new Fragmentclass(); fragobj.setArguments(bundle); 

并在片段onCreateView方法中接收片段:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { String strtext=getArguments().getString("message"); return inflater.inflate(R.layout.fragment, container, false); } 

正如开发者网站所述

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

片段之间的通信应该通过相关的Activity完成。

让我们有以下组件:

活动主持碎片并允许碎片通信

片段将发送数据的第一个片段

FragmentB第二个片段,它将从FragmentA接收数据

片段A的实现是:

 public class FragmentA extends Fragment { DataPassListener mCallback; public interface DataPassListener{ public void passData(String data); } @Override public void onAttach(Context context) { super.onAttach(context); // This makes sure that the host activity has implemented the callback interface // If not, it throws an exception try { mCallback = (OnImageClickListener) context; } catch (ClassCastException e) { throw new ClassCastException(context.toString()+ " must implement OnImageClickListener"); } } public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { // Suppose that when a button clicked second FragmentB will be inflated // some data on FragmentA will pass FragmentB // Button passDataButton = (Button)......... passDataButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (view.getId() == R.id.passDataButton) { mCallback.passData("Text to pass FragmentB"); } } }); } } 

MainActivity的实现是:

 public class MainActivity extends ActionBarActivity implements DataPassListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (findViewById(R.id.container) != null) { if (savedInstanceState != null) { return; } getFragmentManager().beginTransaction() .add(R.id.container, new FragmentA()).commit(); } } @Override public void passData(String data) { FragmentB fragmentB = new FragmentB (); Bundle args = new Bundle(); args.putString(FragmentB.DATA_RECEIVE, data); fragmentB .setArguments(args); getFragmentManager().beginTransaction() .replace(R.id.container, fragmentB ) .commit(); } } 

FragmentB的实现是:

 public class FragmentB extends Fragment{ final static String DATA_RECEIVE = "data_receive"; TextView showReceivedData; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_B, container, false); showReceivedData = (TextView) view.findViewById(R.id.showReceivedData); } @Override public void onStart() { super.onStart(); Bundle args = getArguments(); if (args != null) { showReceivedData.setText(args.getString(DATA_RECEIVE)); } } } 

我希望这会帮助..

来自Developers网站:

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

你可以在活动的帮助下在片段之间进行交stream。 您可以使用这种方法在活动和片段之间进行交stream。

请检查这个链接也。

//在Fragment_1.java中

 Bundle bundle = new Bundle(); bundle.putString("key","abc"); // Put anything what you want Fragment_2 fragment2 = new Fragment_2(); fragment2.setArguments(bundle); getFragmentManager() .beginTransaction() .replace(R.id.content, fragment2) .commit(); 

//在Fragment_2.java中

 Bundle bundle = this.getArguments(); if(bundle != null){ // handle your code here. } 

希望这对你有所帮助。

首先所有答案都是正确的,你可以通过使用Intent来传递除了自定义对象之外的数据。 如果你想传递自定义对象,你必须实现SerialazablePacelable到你的自定义对象类。 我认为这太复杂了,所以如果你的项目很简单,试着使用这个DataCache 。 这提供了超级简单的方式来传递数据。 ref: https : //github.com/kimkevin/AndroidDataCache

1将其设置为View或Activity或Fragment将发送数据

 DataCache.getInstance().push(obj); 

2获取下面的任何地方的数据

public class MainFragment extends Fragment {private YourObject obj;

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); obj = DataCache.getInstance().pop(YourObject.class); } 

片段之间的通信相当复杂(我发现听众的概念实施起来有点困难)。

通常使用“事件总线”来抽象这些通信。这是一个第三方库,为您处理这个通信。

“Otto”是经常用来做这个的,可能值得一看: http : //square.github.io/otto/

传递片段之间的参数。 回答这个问题还是比较晚,但是可以帮助别人! Fragment_1.java

 Bundle i = new Bundle(); i.putString("name", "Emmanuel"); Fragment_1 frag = new Fragment_1(); frag.setArguments(i); FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.content_frame , new Fragment_2()) .commit(); 

然后在你的Fragment_2.java你可以通常在你的onActivityCreated获得参数

  Intent intent = getActivity().getIntent(); if (intent.getExtras() != null) { String name =intent.getStringExtra("name"); } 

将数据从碎片传递到另一个碎片

  • 从第一个片段

     // Set data to pass MyFragment fragment = new MyFragment(); //Your Fragment Bundle bundle = new Bundle(); bundle.putInt("year", 2017) // Key, value fragment.setArguments(bundle); // Pass data to other Fragment getFragmentManager() .beginTransaction() .replace(R.id.content, fragment) .commit(); 
  • 在第二片段

     @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = this.getArguments(); if (bundle != null) { Int receivedYear = bundle.getInt("year", ""); // Key, default value } } 

我已经为像我这样的begginer做了一些非常简单的事情。我在我的activity_main.xml中创build了一个textview并放置

 id=index visibility=invisible 

那么我从第一个片段得到这个textview

 index= (Textview) getActivity().findviewbyid(R.id.index) index.setText("fill me with the value") 

然后在第二个片段我得到的价值

 index= (Textview) getActivity().findviewbyid(R.id.index) String get_the_value= index.getText().toString(); 

希望它有帮助!

这个简单的实现有助于以简单的方式在片段之间传递数据。 想想要将数据从“Frgment1”传递到“Fragment2”

在Fragment1(设置要发送的数据)

  Bundle bundle = new Bundle(); bundle.putString("key","Jhon Doe"); // set your parameteres Fragment2 nextFragment = new Fragment2(); nextFragment.setArguments(bundle); FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_drawer, nextFragment).commit(); 

在Fragment2的onCreateView方法(获取参数)

 String value = this.getArguments().getString("key");//get your parameters Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost 

我认为解决这个问题的一个好方法是使用自定义接口。

假设您有两个片段(A和B),它们在同一个活动中,并且您想要将数据从A发送到B.

界面:

 public interface OnDataSentListener{ void onDataSent(Object data); } 

活动:

  public class MyActivity extends AppCompatActivity{ private OnDataSentListener onDataSentListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_activity); FragmentTransaction trans = getFragmentManager().beginTransaction(); FragmentA fa = new FragmentA(); FragmentB fb = new FragmentB(); fa.setOnDataSentListener(new Listeners.OnDataSentListener() { @Override public void onDataSent(Object data) { if(onDataSentListener != null) onDataSentListener.onDataSent(data); } }); transaction.add(R.id.frame_a, fa); transaction.add(R.id.frame_b, fb); transaction.commit(); } public void setOnDataSentListener(OnDataSentListener listener){ this.onDataSentListener = listener; } } 

片段 – 答:

 public class FragmentA extends Fragment{ private OnDataSentListener onDataSentListener; private void sendDataToFragmentB(Object data){ if(onDataSentListener != null) onDataSentListener.onDataSent(data); } public void setOnDataSentListener(OnDataSentListener listener){ this.onDataSentListener = listener; } } 

片段B:

 public class FragmentB extends Fragment{ private void initReceiver(){ ((MyActivity) getActivity()).setOnDataSentListener(new OnDataSentListener() { @Override public void onDataSent(Object data) { //Here you receive the data from fragment A } }); } }