【问题标题】:NullPointerException when i try to run fragment method from main activity当我尝试从主要活动运行片段方法时出现 NullPointerException
【发布时间】:2020-07-01 00:34:05
【问题描述】:

我是使用片段的新手,我正在尝试从我的主要活动中执行片段方法,该方法比较一个文本视图,然后删除 cookie 并加载一个网站。

这就是我所拥有的:

在 MainActivity 中:

NavigatorFragment navigator = new NavigatorFragment();
navigator.refresh();

在片段中:

public void refresh(){
    if (!textView.getText().toString().equals("Click HERE")){
        cookieManager.removeAllCookie();
        cookieManager.removeSessionCookie();
        myWebView.loadUrl(URL);
    }
}

结果: java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“java.lang.CharSequence android.widget.TextView.getText()”

编辑

抱歉,但忘记提及,虽然片段启动时发生同样的事情,但我之前使用此代码来防止我的片段重新启动:link 所以当我按下我的 BottomNavigationView 的 item4 时,它会在 onCreateView 中打开片段:

textView = root.findViewById(R.id.textView);

当我再次按下它时(没有更改片段)是我想要执行该方法的时候

我再说一遍,当我第一次按下第 4 项 BottomNavigationView 时,它会打开 Fragment 4 并加载其元素,当我第二次按下第 4 项(没有更改片段)时,我希望该方法运行

主要活动:

public class MainActivity extends AppCompatActivity {

/*
Fragment MyFragment;
private NavController navController;
 */
NavigatorFragment navigator = new NavigatorFragment();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.nav_view);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

    replace_fragment(new HomeFragment());
}

private void replace_fragment(Fragment fragment) {

    String tag = fragment.getClass().getSimpleName();
    FragmentTransaction tr = getSupportFragmentManager().beginTransaction();

    Fragment curFrag = getSupportFragmentManager().getPrimaryNavigationFragment();
    Fragment cacheFrag = getSupportFragmentManager().findFragmentByTag(tag);

    if (curFrag != null)
        tr.hide(curFrag);

    if (cacheFrag == null) {
        tr.add(R.id.nav_host_fragment, fragment, tag);
    } else {
        tr.show(cacheFrag);
        fragment = cacheFrag;
    }

    tr.setPrimaryNavigationFragment(fragment);
    tr.commit();

}

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_home:
                replace_fragment(new HomeFragment());
                if (!getSupportActionBar().isShowing()){
                    showBar();
                }
                return true;

            case R.id.navigation_schedule:
                replace_fragment(new ScheduleFragment());
                if (!getSupportActionBar().isShowing()){
                    showBar();
                }
                return true;

            case R.id.navigation_calculators:
                replace_fragment(new CalculatorsFragment());
                if (!getSupportActionBar().isShowing()){
                    showBar();
                }
                return true;

            case R.id.navigation_navigator:
                replace_fragment(new NavigatorFragment());
                if (!getSupportActionBar().isShowing()){
                    navigator.refresh();//**************PROBLEM HERE******************************************
                }
                hideBar();
                return true;
        }
        return false;
    }
};



public void hideBar(){
    if (Build.VERSION.SDK_INT >= 19) {
        // Call some material design APIs here
        Objects.requireNonNull(getSupportActionBar()).hide();
    }
    else {
        // Implement this feature without material design
        getSupportActionBar().hide();
    }
}

public void showBar(){
    if (Build.VERSION.SDK_INT >= 19) {
        // Call some material design APIs here
        Objects.requireNonNull(getSupportActionBar()).show();
    }
    else {
        // Implement this feature without material design
        getSupportActionBar().show();
    }
}

}

**如果从片段代码运行,刷新方法有效

【问题讨论】:

  • 你能说明textView是如何(应该是)初始化的吗?目前这里还不够调试。
  • 完成,我更新了问题希望你能帮助我,谢谢@RyanM
  • 我基本同意 Zain 的回答。你可能还有一个问题是你没有在replace_fragment中设置navigator,所以你使用的是一个尚未启动的片段而不是已经启动的片段。
  • 非常感谢,我会继续测试,希望能解决

标签: android android-fragments


【解决方案1】:

当使用new NavigatorFragment() 实例化片段实例时,不涉及fragment life cycle 的启动。这意味着片段没有被创建、启动、恢复和显示在屏幕上。因此,此时访问片段的视图将返回NullPointerException

所以,你需要做的是在activity布局中为fragment设置一个占位符,并通过该占位符中的addingreplacingfragments启动fragment事务,使fragment通过它的所有生命周期回调方法,并使其有机会在 onCreateView() 生命周期回调中在屏幕上创建其视图(布局),您可以在其中只允许访问底层 TextView 或此片段中的任何其他视图,并使用它们的像你的情况 textView.getText() 这样的方法随后没有 NullPointerException

Here你可以找到如何正确使用片段。

【讨论】:

  • 感谢您的回答,但我认为不是这样,对不起,但忘了提一下,虽然片段启动了同样的事情,但我之前使用此代码来防止我的片段重新启动:link因此,当我按下我的 BottomNavigationView 的 item4 时,它会打开片段,当我再次按下它(没有更改片段)时,我希望执行该方法
猜你喜欢
  • 1970-01-01
  • 2013-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多