在片段与其容器活动之间传递数据
如何在一个片段和它的容器活动之间传递数据? 是否有类似于通过意图在活动之间传递数据?
我读了这个,但没有多大帮助:
http://developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
在你的片段中,你可以调用getActivity()
。
这将使您能够访问创build该片段的活动。 从那里,你显然可以调用活动中的任何一种访问器方法。
例如在Activity上调用getResult()
方法:
((MyActivity) getActivity()).getResult();
尝试使用接口。
任何应该将数据传递回其包含活动的片段都应该声明一个接口来处理和传递数据。 然后确保你的包含活动实现这些接口。 例如:
在你的片段中,声明接口…
public interface OnDataPass { public void onDataPass(String data); }
然后,在onAttach方法中,将包含类的接口实现连接到片段,如下所示:
OnDataPass dataPasser; @Override public void onAttach(Context context) { super.onAttach(context); dataPasser = (OnDataPass) context; }
在你的片段中,当你需要处理数据的传递时,只需在dataPasser对象上调用它:
public void passData(String data) { dataPasser.onDataPass(data); }
最后,在你的包含活动实现 OnDataPass
…
@Override public void onDataPass(String data) { Log.d("LOG","hello " + data); }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle b = getActivity().getIntent().getExtras(); wid = b.getString("wid"); rid = b.getString("rid"); View view = inflater.inflate(R.layout.categoryfragment, container, false); return view; }
最简单的方法,但不build议
您可以从片段访问活动数据:
活动:
public class MyActivity extends Activity { private String myString = "hello"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); ... } public String getMyData() { return myString; } }
分段:
public class MyFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { MyActivity activity = (MyActivity) getActivity(); String myDataFromActivity = activity.getMyData(); return view; } }
在片段与其容器活动之间传递数据
活动:
Bundle bundle = new Bundle(); bundle.putString("message", "Alo Elena!"); FragmentClass fragInfo = new FragmentClass(); fragInfo.setArguments(bundle); transaction.replace(R.id.fragment_single, fragInfo); transaction.commit();
分段:
读取片段中的值
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { String myValue = this.getArguments().getString("message"); ... ... ... }
我不知道这是否是最好的方法不,我一直在谷歌search了很长一段时间,我怎样才能将一个包从一个片段传递到它的容器活动,但我发现所有的数据都是从活动发送到片段(这对我来说有点混乱,因为我是一个新手)。
后来我尝试了一些属于我自己的东西,这正是我想要的。 所以我会在这里发布的情况下,像我这样的人寻找同样的事情。
//从片段传递数据
Bundle gameData = new Bundle(); gameData.putStringArrayList(Constant.KEY_PLAYERS_ARR,players); gameData.putString(Constant.KEY_TEAM_NAME,custom_team_name); gameData.putInt(Constant.KEY_REQUESTED_OVER,requestedOver); Intent intent = getActivity().getIntent(); intent.putExtras(gameData);
//从容器活动中获取包中的数据。
Bundle gameData = getIntent().getExtras(); if (gameData != null) { int over = gameData.getInt(Constant.KEY_REQUESTED_OVER); ArrayList<String> players = gameData.getStringArrayList(Constant.KEY_PLAYERS_ARR); String team = gameData.getString(Constant.KEY_TEAM_NAME); } else if (gameData == null) { Toast.makeText(this, "Bundle is null", Toast.LENGTH_SHORT).show(); }
我使用了实现Date Listeners的AppCompatActivity。 因为我需要编写一个date范围select器,所以碎片成为必需。 而且我还需要容器来接收选定的date以将其返回给父活动。
对于容器活动,这是类声明:
public class AppCompatDateRange extends AppCompatActivity implements DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener
和callback的接口:
@Override public void onDateIniSelected(String dataIni) { Log.i("data inicial:", dataIni); } @Override public void onDateFimSelected(String dataFim) { Log.i("data final:", dataFim); }
callback是string,因为date是查询select中的参数。
片段的代码(基于最初的date片段):
public class DateIniRangeFragment extends Fragment { OnDateIniSelectedListener callbackIni; private DatePicker startDatePicker; public DateIniRangeFragment() { ///required empty constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } ///through this interface the fragment sends data to the container activity public interface OnDateIniSelectedListener { void onDateIniSelected(String dataIni); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ///layout for the fragment View v = inflater.inflate(R.layout.date_ini_fragment, container, false); ///initial date for the picker, in this case, current date startDatePicker = (DatePicker) v.findViewById(R.id.start_date_picker_appcompat); Calendar c = Calendar.getInstance(); int ano = c.get(Calendar.YEAR); int mes = c.get(Calendar.MONTH); int dia = c.get(Calendar.DAY_OF_MONTH); startDatePicker.setSpinnersShown(false); startDatePicker.init(ano, mes, dia, dateSetListener); return v; } ///listener that receives the selected date private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { if (view.isShown()) { ///if the datepicker is on the screen String sDataIni = year + "-" + (monthOfYear + 1) + "-" + dayOfMonth; callbackIni.onDateIniSelected(sDataIni); //apply date to callback, string format } } }; @Override public void onAttach(Activity activity) { super.onAttach(activity); /* * this function guarantees that the container activity implemented the callback interface * */ try { callbackIni = (OnDateIniSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " deve implementar OnDateIniSelectedListener"); } }
}
为了编写容器+片段,我使用了一个ViewPager(AppCompat)和一个扩展了FragmentPagerAdapter的自定义类。 没有对话框。
接口是最好的解决scheme之一:
胶接口:
public interface DataProviderFromActivity { public String getName(); public String getId); }
MyActivity:
public class MyActivity implements DataProviderFromActivity{ String name = "Makarov"; String id = "sys533"; ... ... ... ... ... .... .... ... ... ... ... ... .... .... public String getName(){ return name; }; public String getId(){ return id; }; }
MyFragment:
public class MyFragment extends Fragment{ String fragName = ""; String fragId = ""; ... ... ... ... ... .... .... ... ... ... ... ... .... .... @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); DataProviderFromActivity myActivity= (DataProviderFromActivity) getActivity(); fragName = myActivity.getName(); fragId = myActivity.getId(); ... ... ... ... ... .... .... ... ... ... ... ... .... .... updateFragmentView(); } }
另一种简单的方法是从容器活动的片段中获取从另一活动传来的数据:例如:
Activity_A => Activity_B(片段)
在你的Activity_A中,你创build了一个意图,就像你发送一个数据(string在这里)到另一个活动:
Intent intent = new Intent(getBaseContext(),Activity_B.class); intent.putExtra("NAME", "Value"); startActivity(intent);
在你的Activity_B中包含的Fragment中:
String data = getActivity().getIntent().getExtras();