如何在片段及其容器活动之间传递数据?是否有类似于通过意图在活动之间传递数据的东西?
我读了这篇文章,但并没有太大帮助:http :
//developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
如何在片段及其容器活动之间传递数据?是否有类似于通过意图在活动之间传递数据的东西?
我读了这篇文章,但并没有太大帮助:http :
//developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
Answers:
您可以在片段中致电getActivity()
。
这将使您能够访问创建该片段的活动。显然,您可以从那里调用活动中的任何访问器方法。
例如,getResult()
针对您的Activity 调用的方法:
((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);
}
科特琳
步骤1.创建界面
interface OnDataPass {
fun onDataPass(data: String)
}
步骤2.然后,将接口的包含类的实现连接到onAttach方法(YourFragment)中的片段,如下所示:
lateinit var dataPasser: OnDataPass
override fun onAttach(context: Context) {
super.onAttach(context)
dataPasser = context as OnDataPass
}
步骤3.在片段中,当您需要处理数据传递时,只需在dataPasser对象上调用它即可:
fun passData(data: String){
dataPasser.onDataPass(data)
}
步骤4.最后,在您的活动中实现OnDataPass
class MyActivity : AppCompatActivity(), OnDataPass {}
override fun onDataPass(data: String) {
Log.d("LOG","hello " + data)
}
最简单的方法,但不推荐
您可以从片段访问活动数据:
活动:
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;
}
}
MyActivity
@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;
}
在片段及其容器活动之间传递数据
活动:
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");
...
...
...
}
我不知道这是否是最好的方法,我一直在google上搜索了很长时间,发现如何将Bundle从片段传递到其容器活动,但是我发现的全部是从活动向片段发送数据(因为我是新手,这让我有些困惑)。
后来我尝试了自己想要的东西,完全适合我的需求。所以我将其张贴在这里,以防像我这样的人在寻找相同的东西。
//从Fragment传递数据。
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();
}
接口是最好的解决方案之一:
胶水界面:
public interface DataProviderFromActivity {
public String getName();
public String getId);
}
我的活动:
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();
}
}
我使用了实现日期侦听器的AppCompatActivity。片段是必需的,因为我需要编写日期范围选择器的代码。我还需要容器接收选定的日期,以将其返回到父活动。
对于容器活动,这是类声明:
public class AppCompatDateRange extends AppCompatActivity implements
DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener
以及回调的接口:
@Override
public void onDateIniSelected(String dataIni) {
Log.i("data inicial:", dataIni);
}
@Override
public void onDateFimSelected(String dataFim) {
Log.i("data final:", dataFim);
}
回调是字符串,因为日期是查询选择中的参数。
片段的代码(基于初始日期片段):
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。没有对话。
您只需使用EventBus即可轻松实现出色的工作
3步EventBus
定义事件:
public static class MessageEvent { /* Additional fields if needed */ }
准备订阅者:声明并注释您的订阅方法,可以选择指定线程模式:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
注册和取消注册您的订户。例如,在Android上,活动和片段通常应根据其生命周期进行注册:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
发布事件:
EventBus.getDefault().post(new MessageEvent());
public class Fragmentdemo extends Fragment {
public interface onDemoEventListener {
public void demoEvent(String s);
}
onDemoEventListener demoEventListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
demoEventListener = (onDemoEventListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onDemoEventListener");
}
}
final String LOG_TAG = "TAG";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragmentdemo, null);
Button button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
demoEventListener.someEvent("Test text to Fragment1");
}
});
enter code here
return v;
}
}
从另一个活动传递的另一种简单的获取数据的方式是在容器活动的片段中:例如:
Activity_A => Activity_B(片段)
在Activity_A中,您将创建一个意图,就像您将数据(此处为String)发送到另一个活动:
Intent intent = new Intent(getBaseContext(),Activity_B.class);
intent.putExtra("NAME", "Value");
startActivity(intent);
在片段中,包含在您的Activity_B中:
String data = getActivity().getIntent().getExtras();
getBaseContext()
给我以下错误:The method getBaseContext() is undefined for the type new View.OnClickListener(){}