简体   繁体   English

尝试查找ViewById时抛出NullpointerException

[英]Nullpointerexception thrown when trying to findViewById

I have the following Activity: 我有以下活动:

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

}

I get a NPE when I try to invoke findViewByID for R.id.loginButton , and I'm guessing this is because loginButton is within a separate Fragment, which I have as: 当我尝试为R.id.loginButton调用findViewByID时,我得到了NPE,我猜这是因为loginButton在单独的Fragment中,我具有:

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

    }
}

However, I am unsure of how to fix this so that I can find the loginButton ID. 但是,我不确定如何解决此问题,以便可以找到loginButton ID。 I haven't worked with fragments before, so I realize I may be using them/implementing them incorrectly. 我以前没有使用过片段,所以我意识到我可能正在使用它们/错误地实现了它们。 fragment_main contains a few buttons in a LinearLayout , and activity_main has nothing but a single FrameLayout . fragment_mainLinearLayout包含几个按钮,而activity_main除了一个FrameLayout什么也没有。

Try to implement your onCreateView(...) in Fragment like 尝试在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;
}

The Button is in the fragment layout ( fragment_main.xml ) and not in the activity layout ( activity_main.xml ). Button在片段布局( fragment_main.xml )中,不在活动布局( activity_main.xml )中。 onCreate() is too early in the lifecycle to find it in the activity view hierarchy, and a null is returned. onCreate()在生命周期中为时过早,无法在活动视图层次结构中找到它,并返回null Invoking a method on null causes the NPE. null上调用方法会导致NPE。

Write code to initialize button from fragment becuase your button is into fragment layout not into activity's layout. 从片段编写代码以初始化按钮,因为您的按钮进入片段布局而不是活动布局。

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

And remove the login button related code from onCreate of Activity . 并从Activity onCreate中删除与登录按钮相关的代码。

findViewById() works with reference to a root view. findViewById()可以参考根视图。 Without having a view in the first place will throw a null pointer exception 如果不首先查看,将抛出空指针异常

In any activity you set a view by calling setContentView(someView); 在任何活动中,您都可以通过调用setContentView(someView);设置视图setContentView(someView); . Thus when you call findViewById() , its with reference to the someView . 因此,当您调用findViewById() ,其引用了someView Also findViewById() finds the id only if its in that someView . 同样,findViewById()仅在该someView找到ID。 So in you case null pointer exception 所以在这种情况下,空指针异常

For fragments, adapters, activity, .... any view's findViewById() will only find if the id exixts in the view Alternately if you are inflating a view, then you can also use inflatedView.findViewById() to get a view from that inflatedView 对于片段,适配器,活动...。任何视图的findViewById()仅会查找id是否在视图中消失,或者,如果您对视图进行膨胀,则还可以使用inflatedView.findViewById()从该视图中获取视图。 inflatedView

In short make sure you have the id in your layout you are referring to or make findViewById() call in appropriate place(Ex. adapters getView() , activity's onCreate() or onResume() or onPause() , fragments onCreateView() , ....) 简而言之,请确保您在要引用的布局中包含id ,或者在适当的位置调用findViewById() (例如adapters getView() ,活动的onCreate()onResume()onPause() ,片段onCreateView() , ....)

Also have an idea about UI & background thread's as you cannot efficiently update UI in bg-threads 也有关于UI和后台线程的想法,因为您不能有效地更新bg-threads中的UI

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM