【问题标题】:TextView inside Fragment in ViewPager is null on orientation changeViewPager 中 Fragment 内的 TextView 在方向更改时为空
【发布时间】:2019-05-27 00:29:45
【问题描述】:

我在里面有一个MainActivity,我用Fragments 创建了ViewPager。我正在使用 savedInstanceState 存储值以在方向更改后设置TextView。我也想改变价值,例如使用MainActivity 中的按钮。 Button 可以正常工作,但是如果我更改方向,则 Button 无法在 Fragment 中设置 TextView,因为 TextView 现在为空。

MyFragment

public class MyFragment extends Fragment {

    private TextView textView;
    private String info;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.item_weather, container, false);
        textView = view.findViewById(R.id.text_view);
        Bundle bundle = getArguments();
        info = bundle.getString("info");
        setInfo(info);
        return view;

    }

    public void setInfo(String info) {
        this.info = info;
        textView.setText(info); //here is the error
    }
}

MainActivity.javaOnCreate

myFragment = new MyFragment();
viewPager = findViewById(R.id.viewpager);
viewPager.setOffscreenPageLimit(10);

List<Fragment> fragments = new ArrayList<>();
fragments.add(myFragment);

pagerAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
viewPager.setAdapter(pagerAdapter);

MyPagerAdapter 看起来像这样:

public class MyPageAdapter extends FragmentStatePagerAdapter {

    private List<Fragment> fragments;

    public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

正如我所说的一切正常,但如果我使用 Button 进行方向更改后出现错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

有什么办法解决这个问题吗?

编辑: 完全错误

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.app.myapp, PID: 15400
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at com.example.app.myapp.fragments.myFragment.setInfo(myFragment.java:53)
        at com.example.app.myapp.MainActivity.onOptionsItemSelected(MainActivity.java:195)
        at android.app.Activity.onMenuItemSelected(Activity.java:3543)
        at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:407)
        at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
        at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
        at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
        at android.support.v7.app.ToolbarActionBar$2.onMenuItemClick(ToolbarActionBar.java:63)
        at android.support.v7.widget.Toolbar$1.onMenuItemClick(Toolbar.java:203)
        at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:780)
        at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
        at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
        at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
        at android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:127)
        at android.widget.AdapterView.performItemClick(AdapterView.java:318)
        at android.widget.AbsListView.performItemClick(AbsListView.java:1159)
        at android.widget.AbsListView$PerformClick.run(AbsListView.java:3136)
        at android.widget.AbsListView$3.run(AbsListView.java:4052)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

【问题讨论】:

  • 您是否从其他任何地方调用 setInfo?什么是完整的堆栈跟踪?
  • 我从 MainActivity 中调用它,例如 myFragment.setInfo("something")
  • 我添加了完整的错误
  • 这很有趣,你的bug实际上在MainActivity中。可能是您初始化片段的方式。等等OptionsItemSelected中断
  • 我调试了它,似乎在旋转后TextView 不为空。但是,如果 setInfo 尝试设置 TextView 会抛出错误

标签: java android android-fragments android-viewpager


【解决方案1】:

进入fragment尝试在onViewCreated方法上初始化textView:


@Override
public View onViewCreated(view: View, savedInstanceState: Bundle) {

   // Your initialization code here

} 

【讨论】:

  • 我在onViewCreated 中初始化TextView 但问题是我在旋转更改后创建了两个不同的片段。
【解决方案2】:

解决方案:

好的,EpicPandaForce 感谢您的提示。

为了解决这个问题,我在MainActivity中使用了

@Override
    protected void onResume() {
        super.onResume();
        viewPager.setAdapter(pagerAdapter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        viewPager.setAdapter(null);
    }

【讨论】:

  • 这听起来并不能解决你很可能遇到的崩溃,如果你这样做stackoverflow.com/questions/49046773/…
  • 但是在初始化Fragment之前我会在MainActivity中检查Fragment是否为null,所以我不会创建太多Fragment,对吗?
  • 问题不在于你是否创建了太多,而是当系统重新创建它们时,你仍然与它的正确实例对话。
  • 那么,您的建议是什么? :)
  • 我现在不记得 FragmentStatePagerAdapter 的代码,但是对于常规的 FragmentStatePagerAdapter,想法是始终在getItem() 内创建一个新的片段实例,然后将实例获取到片段使用stackoverflow.com/questions/54279509/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 2015-01-14
相关资源
最近更新 更多