问题
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:
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. 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
.
回答1:
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
.
回答2:
Try to implement your onCreateView(...)
in Fragment
like
@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
). onCreate()
is too early in the lifecycle to find it in the activity view hierarchy, and a null
is returned. Invoking a method on null
causes the NPE.
回答3:
findViewById()
works with reference to a root view.
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);
.
Thus when you call findViewById()
, its with reference to the someView
.
Also findViewById() finds the id only if its in that someView
. 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
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()
, ....)
Also have an idea about UI & background thread's as you cannot efficiently update UI in bg-threads
来源:https://stackoverflow.com/questions/23869019/nullpointerexception-thrown-when-trying-to-findviewbyid