尝试findViewById时抛出Nullpointerexception

时间:2014-05-26 11:26:12

标签: java android nullpointerexception android-framelayout

我有以下活动:

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);
        }
    });

}

当我尝试为findViewByID调用R.id.loginButton时,我得到了一个N​​PE,我猜这是因为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_main包含LinearLayout中的几个按钮,activity_main只有一个FrameLayout

3 个答案:

答案 0 :(得分:2)

尝试在onCreateView(...)中实施Fragment

@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。

答案 1 :(得分:1)

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

@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;
}

并从onCreate的{​​{1}}中删除与登录按钮相关的代码。

答案 2 :(得分:0)

findViewById()可以参考根视图。 如果没有视图,则会抛出空指针异常

在任何活动中,您都可以通过调用setContentView(someView);来设置视图。 因此,当您致电findViewById()时,请参考someView。 此外,findViewById()仅在someView中找到该ID。所以在你的情况下空指针异常

对于片段,适配器,活动,....任何视图的findViewById()只会查找视图中的id是否出现 或者,如果您要对视图进行充气,那么您也可以使用inflatedView.findViewById()inflatedView获取视图

简而言之,请确保您所指的布局中有id或在适当的位置拨打findViewById()电话(例如适配器getView(),活动' s {{ 1}}或onCreate()onResume(),片段onPause(),....)

还有关于UI&后台线程,因为你无法在bg-threads中有效地更新UI