1

我需要在 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");
}

我的日志猫:

10-08 18:34:49.036 10293-10293/com.org.feedme.cisvmeeting.activities W/dalvikvm: threadid=1: 线程退出未捕获异常 (group=0x41640d88) 10-08 18:34:49.056 10293-10293 /com.org.feedme.cisvmeeting.activities E/AndroidRuntime:致命异常:主进程:com.org.feedme.cisvmeeting.activities,PID:10293 java.lang.NullPointerException at com.org.feedme.fragments.NewEventFragment.attemptCreate (NewEventFragment.java:116) 在 com.org.feedme.fragments.NewEventFragment$1.onClick(NewEventFragment.java:61) 在 android.view.View.performClick(View.java:4569) 在 android.view.View$PerformClick .run(View.java:18570) 在 android.os.Handler.handleCallback(Handler.java:743) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os。Looper.loop(Looper.java:136) 在 android.app.ActivityThread.main(ActivityThread.java:5212) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke( Method.java:515) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602) 在 dalvik.system .NativeStart.main(本机方法)ZygoteInit.main(ZygoteInit.java:602) 在 dalvik.system.NativeStart.main(Native Method)ZygoteInit.main(ZygoteInit.java:602) 在 dalvik.system.NativeStart.main(Native Method)

感谢所有的帮助!

4

2 回答 2

1

给定答案的替代方法是使用事件。如果你真的想避免耦合你的代码——意味着摆脱类之间不必要的依赖,在你的 Activity 中拥有一个变量不是一个好主意。这是我的建议:

  • 将 EventBus 库添加到您的 Gradle 文件中:

     compile 'de.greenrobot:eventbus:2.4.0'
    
  • 创建一个简单的普通 java 类来表示您的事件:

    public class CalendarDateSelectedEvent{
       private String currentDate;
    
       public CalendarDateSelectedEvent(String date){
    
          this.currentDate = date;
       }
    
       public String getCurrentDate(){
    
          return currentDate;
       }
    }
    
  • Inside your first fragment where a date is picked, you can post an event to your second fragment as soon as the date is selected like this:

    //somewhere when  a date is selected
    onSelectedDayChanged(String dateSelected){
       EventBus.getDefault().post(new CalendarDateSelectedEvent(dateSelected));
    }
    
  • Finally, inside your second fragment, do the following:

    //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.
    }
    

At this point, you might be asking, why all the hussle to have all these code; but the answer is simple: the activity doesn't have to really know what is happening in either fragments. You have eliminated unnecessary coupling in your code.

If you ever change the activity to do something else, you won't have to change the fragment code.

I hope this helps you see the difference between the two approaches to communicating between fragments!

The first approach (the answer you accepted, involves 3 parties while the second approach involves only 2 parties). It is up to you to choose.

Enjoy!

于 2015-10-08T22:27:59.267 回答
0

如果它们是同一活动中的片段,您可以使用活动非常轻松地访问它们之间的数据。

第 1 步:在您的 : 中声明一个字符串 curDate Activity

public String curDate; //you could also make it private and add a public getter & setter

第 2 步:在您NewDateFragment的 中onSelectedDayChange(),将活动的 curDate 设置为您刚刚计算的当前日期:

getActivity().curDate = curDate;

第 3 步:在您的NewEventFragment中,只需从活动中获取值:

public String curDate = getActivity().curDate;
于 2015-10-08T21:50:11.313 回答