Search code examples
androidnulloncreatefindviewbyid

findViewbyId returns null - but not when put into a button onClick listener


I want to access a TextView to exhange its label. However, findViewById seems to return null when the code is in onCreate(), onResume() or onStart(). The application crashes only if the

//if(Day != null) 

is not commented by //.

The code snippet works fine when put into a onClickListener of a Button, no NullPointerException.

I have really read a lot of solutions yet (cleaning the project, moving the code to onCreateView etc.), but none of them worked for me. So I'm really hoping for your help :P

My Activity is

package edu.uahwi.smac;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;

public class HoursActivity extends ActionBarActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //hides the title bar
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.activity_hours);

    final PlaceholderFragment fragment = new PlaceholderFragment();
    Bundle args = new Bundle();
    long ChosenDate = (long) getIntent().getExtras().getLong("DateLong");
    args.putLong("DateLong", ChosenDate);
    fragment.setArguments(args);
    getSupportFragmentManager().beginTransaction().add(R.id.container, fragment).commit();

    /*if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }
    */
    /*
    TextView Day1 = (TextView) findViewById(R.id.textViewDay);
    //if(Day != null)
        Day1.setText(String.valueOf(ChosenDate));*/

}

public void onStart()
{

}

public void Hour2onClick(View v)
{
    startActivity( new Intent("edu.uahwi.smac.BookingConfirmedActivity"));
}

public void buttonClick(View v)
{
    //startActivity( new Intent("edu.uahwi.smac.BookingConfirmedActivity"));


}


@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.hours, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}


/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    private long chosenDate; // = 10l; 
                             //= (long) getIntent().getExtras().getLong("DateLong");

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

        TextView Day1 = (TextView) rootView.findViewById(R.id.textViewDay);
        Day1.setText(String.valueOf(chosenDate));

        return rootView;
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        Bundle args = getArguments();
        if (args != null)
            chosenDate = args.getLong("DateLong");
    }
}

}

The start of the XML-Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="edu.uahwi.smac.HoursActivity$PlaceholderFragment" >

<TextView
    android:id="@+id/textViewDay1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center"
    android:paddingBottom="15dp"
    android:text="@string/ChosenDay"
    android:textSize="25sp" />

<ScrollView
    android:id="@+id/scrollView1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="208dp"
        android:orientation="vertical" >

And finally my Stack-Trace:

05-19 23:12:01.649: W/dalvikvm(1596): threadid=1: thread exiting with uncaught 

exception (group=0xb2addba8)
05-19 23:12:01.669: E/AndroidRuntime(1596): FATAL EXCEPTION: main
05-19 23:12:01.669: E/AndroidRuntime(1596): Process: edu.uahwi.smac, PID: 1596
05-19 23:12:01.669: E/AndroidRuntime(1596): java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.uahwi.smac/edu.uahwi.smac.HoursActivity}: java.lang.NullPointerException
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.os.Handler.dispatchMessage(Handler.java:102)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.os.Looper.loop(Looper.java:136)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.ActivityThread.main(ActivityThread.java:5017)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at java.lang.reflect.Method.invokeNative(Native Method)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at java.lang.reflect.Method.invoke(Method.java:515)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at dalvik.system.NativeStart.main(Native Method)
05-19 23:12:01.669: E/AndroidRuntime(1596): Caused by: java.lang.NullPointerException
05-19 23:12:01.669: E/AndroidRuntime(1596):     at edu.uahwi.smac.HoursActivity.onCreate(HoursActivity.java:36)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.Activity.performCreate(Activity.java:5231)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
05-19 23:12:01.669: E/AndroidRuntime(1596):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
05-19 23:12:01.669: E/AndroidRuntime(1596):     ... 11 more

Solution

  • That TextView is in the fragment. You need to move the code that sets the text value to the Fragment's onCreateView(), when you are sure the fragment's views exist. Like this:

    private long chosenDate;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.your_fragment_layout, container, false);
    
        TextView Day1 = (TextView) findViewById(R.id.textViewDay1);
        Day1.setText(String.valueOf(chosenDate));
    

    And you can pass in chosenDate to the fragment arguments so it will be available to the fragment. Start your fragment like this from the Activity:

    final PlaceholderFragment fragment = new PlaceholderFragment();
    Bundle args = new Bundle();
    long ChosenDate = (long) getIntent().getExtras().getLong("DateLong");
    args.putLong("DateLong", ChosenDate);
    fragment.setArguments(args);
    fm.beginTransaction().add(R.id.container, fragment).commit();
    

    Then in the fragment's onCreate, you can extract the argument and set the local private long to that value, so it will be available later in the onViewCreate call:

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    
        Bundle args = getArguments();
        if (args != null)
            chosenDate = args.getLong("DateLong");