在不使用 activity 的情况下在两个片段之间传递字符串
Pass String between two fragments without using an activity
我需要在 NewDateFragment 和 NewEventFrament 之间传递字符串 curDate,我看到很多人使用 Bundle,但使用这些我仍然有 NullPointerException。
我将 CalendarView 转换为一个名为 curDate 的字符串。
public class NewDateFragment extends Fragment {
public String curDate;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_newdate,
container, false);
CalendarView calendar = (CalendarView) view.findViewById(R.id.calendarView);
//sets the listener to be notified upon selected date change.
calendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(CalendarView view, int year, int month, int day) {
curDate = day + "/" + month + "/" + year;
NewDateFragment fragment = new NewDateFragment();
Bundle bundle = new Bundle();
bundle.putString("date", curDate);
fragment.setArguments(bundle);
Log.d("Current Date:", curDate);
}
});
}
public class NewEventFragment extends Fragment {
// relative code inside onCreateView
Bundle b = getActivity().getIntent().getExtras();
final String dDate = b.getString("date");
}
我的Logcat:
10-08 18:34:49.036 10293-10293/com.org.feedme.cisvmeeting.activities W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41640d88)
10-08 18:34:49.056 10293-10293/com.org.feedme.cisvmeeting.activities E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.org.feedme.cisvmeeting.activities, PID: 10293
java.lang.NullPointerException
at com.org.feedme.fragments.NewEventFragment.attemptCreate(NewEventFragment.java:116)
at com.org.feedme.fragments.NewEventFragment.onClick(NewEventFragment.java:61)
at android.view.View.performClick(View.java:4569)
at android.view.View$PerformClick.run(View.java:18570)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
感谢大家的帮助!
如果它们是同一个 activity 中的片段,您可以使用 activity.
非常轻松地访问它们之间的数据
第 1 步:在 Activity
:
中声明一个字符串 curDate
public String curDate; //you could also make it private and add a public getter & setter
第 2 步:在您的 NewDateFragment
中,在 onSelectedDayChange()
中,将 activity 的 curDate 设置为您刚刚计算的当前日期:
getActivity().curDate = curDate;
第 3 步:在您的 NewEventFragment
中,只需从 activity:
中获取值
public String curDate = getActivity().curDate;
给定答案的替代方法是使用事件。如果你真的想避免耦合你的代码——意味着摆脱 class 之间不必要的依赖,在你的 Activity 中有一个变量不是一个好主意。这是我的建议:
将 EventBus 库添加到您的 Gradle 文件:
compile 'de.greenrobot:eventbus:2.4.0'
创建一个简单的普通旧 java class 来代表您的活动:
public class CalendarDateSelectedEvent{
private String currentDate;
public CalendarDateSelectedEvent(String date){
this.currentDate = date;
}
public String getCurrentDate(){
return currentDate;
}
}
在您选择日期的第一个片段中,您可以 post 在选择日期后立即向第二个片段发送事件,如下所示:
//somewhere when a date is selected
onSelectedDayChanged(String dateSelected){
EventBus.getDefault().post(new CalendarDateSelectedEvent(dateSelected));
}
最后,在您的第二个片段中,执行以下操作:
//could be inside onCreate(Bundle savedInstanceState) method
@Override
public void onCreate(Bundle saveInstanceState){
//......
EventBus.getDefault().register(this);
}
@Override
public void onDestroy(){
super.onDestroy();
EventBus.getDefault().unregister(this);
}
//very important piece here to complete the job
public void onEvent(CalenderDateSelectedEvent event){
String currentDate = event.getCurrentDate();
//you can now set this date to view.
}
在这一点上,您可能会问,为什么要这么麻烦地拥有所有这些代码?但答案很简单:activity 不必真正知道这两个片段中发生了什么。您已经消除了代码中不必要的耦合。
如果您更改 activity 以执行其他操作,则无需更改片段代码。
我希望这可以帮助您了解片段间通信的两种方法之间的区别!
第一种方法(您接受的答案涉及3方,而第二种方法仅涉及2方)。由你选择。
尽情享受吧!
我需要在 NewDateFragment 和 NewEventFrament 之间传递字符串 curDate,我看到很多人使用 Bundle,但使用这些我仍然有 NullPointerException。
我将 CalendarView 转换为一个名为 curDate 的字符串。
public class NewDateFragment extends Fragment {
public String curDate;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_newdate,
container, false);
CalendarView calendar = (CalendarView) view.findViewById(R.id.calendarView);
//sets the listener to be notified upon selected date change.
calendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(CalendarView view, int year, int month, int day) {
curDate = day + "/" + month + "/" + year;
NewDateFragment fragment = new NewDateFragment();
Bundle bundle = new Bundle();
bundle.putString("date", curDate);
fragment.setArguments(bundle);
Log.d("Current Date:", curDate);
}
});
}
public class NewEventFragment extends Fragment {
// relative code inside onCreateView
Bundle b = getActivity().getIntent().getExtras();
final String dDate = b.getString("date");
}
我的Logcat:
10-08 18:34:49.036 10293-10293/com.org.feedme.cisvmeeting.activities W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41640d88) 10-08 18:34:49.056 10293-10293/com.org.feedme.cisvmeeting.activities E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.org.feedme.cisvmeeting.activities, PID: 10293 java.lang.NullPointerException at com.org.feedme.fragments.NewEventFragment.attemptCreate(NewEventFragment.java:116) at com.org.feedme.fragments.NewEventFragment.onClick(NewEventFragment.java:61) at android.view.View.performClick(View.java:4569) at android.view.View$PerformClick.run(View.java:18570) at android.os.Handler.handleCallback(Handler.java:743) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5212) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602) at dalvik.system.NativeStart.main(Native Method)
感谢大家的帮助!
如果它们是同一个 activity 中的片段,您可以使用 activity.
非常轻松地访问它们之间的数据第 1 步:在 Activity
:
public String curDate; //you could also make it private and add a public getter & setter
第 2 步:在您的 NewDateFragment
中,在 onSelectedDayChange()
中,将 activity 的 curDate 设置为您刚刚计算的当前日期:
getActivity().curDate = curDate;
第 3 步:在您的 NewEventFragment
中,只需从 activity:
public String curDate = getActivity().curDate;
给定答案的替代方法是使用事件。如果你真的想避免耦合你的代码——意味着摆脱 class 之间不必要的依赖,在你的 Activity 中有一个变量不是一个好主意。这是我的建议:
将 EventBus 库添加到您的 Gradle 文件:
compile 'de.greenrobot:eventbus:2.4.0'
创建一个简单的普通旧 java class 来代表您的活动:
public class CalendarDateSelectedEvent{ private String currentDate; public CalendarDateSelectedEvent(String date){ this.currentDate = date; } public String getCurrentDate(){ return currentDate; } }
在您选择日期的第一个片段中,您可以 post 在选择日期后立即向第二个片段发送事件,如下所示:
//somewhere when a date is selected onSelectedDayChanged(String dateSelected){ EventBus.getDefault().post(new CalendarDateSelectedEvent(dateSelected)); }
最后,在您的第二个片段中,执行以下操作:
//could be inside onCreate(Bundle savedInstanceState) method @Override public void onCreate(Bundle saveInstanceState){ //...... EventBus.getDefault().register(this); } @Override public void onDestroy(){ super.onDestroy(); EventBus.getDefault().unregister(this); } //very important piece here to complete the job public void onEvent(CalenderDateSelectedEvent event){ String currentDate = event.getCurrentDate(); //you can now set this date to view. }
在这一点上,您可能会问,为什么要这么麻烦地拥有所有这些代码?但答案很简单:activity 不必真正知道这两个片段中发生了什么。您已经消除了代码中不必要的耦合。
如果您更改 activity 以执行其他操作,则无需更改片段代码。
我希望这可以帮助您了解片段间通信的两种方法之间的区别!
第一种方法(您接受的答案涉及3方,而第二种方法仅涉及2方)。由你选择。
尽情享受吧!