java - 无法通过捆绑将字符串从一个片段发送到另一个片段
问题描述
我正在尝试通过捆绑将两个字符串发送到下一个片段,但应用程序甚至在我到达第一个片段之前就崩溃了。
我在第二个片段中收到此错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.guessit, PID: 22360
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
at com.example.android.guessit.GameFlow.FragmentAnswer1.onCreateView(FragmentAnswer1.java:125)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1696)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:299)
at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:259)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:669)
at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:631)
at androidx.viewpager.widget.ViewPager.setCurrentItem(ViewPager.java:612)
at com.example.android.guessit.GameFlow.GameActivity.setViewPager(GameActivity.java:152)
at com.example.android.guessit.GameFlow.FragmentOneCategory$6.onClick(FragmentOneCategory.java:190)
at android.view.View.performClick(View.java:7352)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
我知道这意味着我试图在第二个片段中接收的字符串值意味着该字符串没有值,但我不知道问题出在哪里,因为我尝试发送的字符串不为空.
这是我在第一个片段中用于捆绑的代码(在 中使用这个onCreatView
):
FragmentAnswer1 frag1 = new FragmentAnswer1();
Bundle args = new Bundle();
args.putString("question_1", question);
args.putString("answer_1", answer);
frag1.setArguments(args);
getFragmentManager().beginTransaction().add(R.id.container, frag1).commit(); // there is a message that says that "beginTransaction" may produce a nullPointer
这是在第二个片段中接收字符串的代码(目前也在onCreateView
)
question = getArguments().getString("question_1"); // error is in this line
answer = getArguments().getString("answer_1");
question1.setText(question);
rightAnswer.setText(answer);
我已经尝试将上面的代码移动到onStart
方法中,但我仍然得到同样的错误。我也尝试使用此解决方案,但它对我不起作用。我没有找到有关如何解决问题的任何其他解决方案或方法。
如果您需要更多信息,请告诉我。任何帮助深表感谢!
解决方案
我现在找到了在拥有 ViewPager 时将数据从一个 Fragment 发送到另一个 Fragment 的正确方法。我们必须使用 ViewModel。
首先,我们必须创建一个 ViewModel,在这种情况下,我们的目标是从 Fragment 1 向 Fragment 2 发送一个 String。下面是 ViewModel 的代码,其中包含 String 的 Getter 和 Setter 方法:
public class ViewModelString extends ViewModel {
private MutableLiveData<String> mString = new MutableLiveData<>();
public MutableLiveData<String> getmString() {
return mString;
}
public void setmString(MutableLiveData<String> mString) {
this.mString = mString;
}
}
然后在我们想要发送字符串的片段 1 中,我们首先需要初始化 ViewModel onCreate
。
public class Fragment1 extends Fragment {
private ViewModelString viewModel;
public Fragment1() {
// Required empty public constructor
}
public static Fragment1 newInstance() {
return new Fragment1();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// initialize ViewModel here
viewModel = ViewModelProviders.of(requireActivity()).get(ViewModelString.class);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
String hello = "hello";
viewModel.setmString(hello);
}
}
然后在第二个 Fragment 中,我们还必须首先初始化 viewModel,然后创建一个观察者。然后,我们在这里获取存储在 ViewModel 中的 String 并将 TextView 设置为其值:
public class Fragment2 extends Fragment {
private ViewModelString viewModel;
public Fragment2() {
// Required empty public constructor
}
public static Fragment2 newInstance() {
return new Fragment2();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// initialize ViewModel here
viewModel = ViewModelProviders.of(requireActivity()).get(ViewModelString.class);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
TextView textView = findViewById(R.id.yourTextViewId);
// Gets the string
viewModel.getmString().observe(requireActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
}
...
}
我希望这对任何人都有帮助!请随时编辑我的帖子。
推荐阅读
- ios - 如何在条件视图中平滑过渡?
- react-native - ViewPager 和 FlatList 有什么区别?
- spring-webflux - 是否有任何生成 Spring Webflux 优化的 OCI 图像的构建包?
- r - ggRadar 突出显示雷达中的最高值
- android - 如何从颤振代码更新主屏幕小部件
- python - 使用列标题将 Python JSON 数据流式传输到 PySpark Dataframe
- javascript - 如何在 React index.js 中编写脚本?
- symlink - 找到损坏的符号链接,然后在备份中找到相应的文件并重新链接
- javascript - 迭代嵌套数据 JS
- typescript - eslinting 问题和我的打字稿反应应用程序正在崩溃