【问题标题】:Nullpointerexception thrown when trying to findViewById尝试 findViewById 时抛出 Nullpointerexception
【发布时间】:2014-07-15 03:53:25
【问题描述】:

我有以下活动:

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new StartFragment())
                .commit();
    }

    Button login = (Button) findViewById(R.id.loginButton);

    login.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            Intent intent = new Intent(MainActivity.this,LoginActivity.class);
            startActivity(intent);
        }
    });

}

当我尝试为R.id.loginButton 调用findViewByID 时,我得到了一个 NPE,我猜这是因为loginButton 在一个单独的片段中,我有:

public static class StartFragment extends Fragment {

    public StartFragment() {
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_main, container, false);

    }
}

但是,我不确定如何解决此问题,以便找到 loginButton ID。我以前没有使用过片段,所以我意识到我可能正在错误地使用它们/实现它们。 fragment_mainLinearLayout 中包含几个按钮,而activity_main 只有一个FrameLayout

【问题讨论】:

标签: java android nullpointerexception android-framelayout


【解决方案1】:

尝试在Fragment 中实现你的onCreateView(...) 喜欢

@Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
 Bundle savedInstanceState) {
 View rootView = inflater.inflate(R.layout.fragment_main, container,
  false);

 View something = rootView.findViewById(R.id.something);
 something.setOnClickListener(new View.OnClickListener() { ... });

return rootView;
}

Button 在片段布局 (fragment_main.xml) 中,而不是在活动布局 (activity_main.xml) 中。 onCreate() 在生命周期中太早,无法在活动视图层次结构中找到它,并返回 null。在 null 上调用方法会导致 NPE。

【讨论】:

    【解决方案2】:

    编写代码以从片段初始化按钮,因为您的按钮进入片段布局而不是活动布局。

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);
        Button login = (Button) rootView.findViewById(R.id.loginButton);
        login.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View arg0) {
    
                Intent intent = new Intent(MainActivity.this,
                        LoginActivity.class);
                startActivity(intent);
            }
        });
    
        return rootView;
    }
    

    并从ActivityonCreate中删除登录按钮相关代码。

    【讨论】:

      【解决方案3】:

      findViewById() 参考根视图工作。 一开始没有视图会抛出空指针异常

      在任何活动中,您都可以通过调用setContentView(someView); 来设置视图。 因此,当您调用 findViewById() 时,它引用了 someView。 此外 findViewById() 仅在其位于 someView 中时才查找 id。所以在你的情况下,空指针异常

      对于片段、适配器、活动,......任何视图的findViewById() 只会在视图中出现 id 时找到 或者,如果您正在膨胀视图,那么您也可以使用 inflatedView.findViewById() 从该 inflatedView 获取视图

      简而言之,确保您在您所指的布局中有 id 或在适当的位置进行 findViewById() 调用(例如适配器 getView(),活动的 onCreate()onResume()onPause() ,片段onCreateView(), ....)

      还有一个关于 UI 和后台线程的想法,因为您无法在 bg-threads 中有效地更新 UI

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-23
        相关资源
        最近更新 更多