JRivera294 JRivera294 - 6 days ago 5
Android Question

findViewById() returns null when I call it in onCreate()

I'm having a problem with the findViewById on my first android app. I'm trying to call this function but always return null.

My app have 2 activities. In the second activity (activity_display_message) I have this code:

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

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

//Obtener el mensaje desde el intent en MainActivity
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

//Buscar el textview en la vista
TextView textView = (TextView) findViewById(R.id.texto);
textView.setText(message);
}


And this is the fragment_display_message.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.example.app.DisplayMessageActivity$PlaceholderFragment">

<TextView
android:id="@+id/texto"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />




I don't know why it return NULL and generate a
NullPointerException
when I try to do a
setText()
. I'm calling the correct Id and declaring it on the XML too. And I'm calling the
setContextView()
on the
onCreate()
.

Sorry if this question is too obvious (I think that I'm ignoring something obvious) but I'm new on android development.

EDIT: Logcat error:

02-10 10:25:58.960 1031-1031/com.example.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.app, PID: 1031
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.DisplayMessageActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.app.DisplayMessageActivity.onCreate(DisplayMessageActivity.java:35)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)


          

Edit:



Problem solved. Just need move the code from
onCreate()
to
onCreateView()
and edit the references.

onCreate()
will be the default.

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

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


And the
onCreateView()
on
PlaceholderFragment
:

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

//Obtener el mensaje desde el intent en MainActivity
Intent intent = getActivity().getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

//Buscar el textview en la vista
TextView textView = (TextView) rootView.findViewById(R.id.texto);
textView.setText(message);

return rootView;
}

Answer

Activity findViewById() searches the activity's view hierarchy set with setContentView() for the given view id. The view you appear to be looking for is in a fragment and not in the activity hierarchy (yet). Fragment transactions are not immediate either so even if you add it to the container in the activity hierarchy, it is not attached there right away but only when the transaction is processed.

In theory it's possible to synchronously execute pending fragment transactions with executePendingTransactions(). However, it's better to just move the code that touches a fragment's views in its onCreateView(). Fragments and their hosting activities are supposed to be relatively independent of each other, so an activity accessing a fragment's internals should be avoided.