JDJ
JDJ

Reputation: 4328

Why is setting the text of a Spinner in onCreateView throwing a null pointer exception?

I want to set the superficial text on a Spinner without having that text appear as an item in the spinner drop-down.

I'm getting a reference to the Spinner's TextView like this:

TextView tv = (TextView) spinner.findViewById(android.R.id.text1);
tv.setText("TEST");

The problem is that it throws a NPE when calling the above code from the main body of onCreateView().

But if I comment out these lines in the main body of onCreateView(), it works fine when I set the text using the above code inside the spinner's OnItemSelectedListener.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) 
{
    View v = inflater.inflate(R.layout.my_fragment, parent, false);

    spinner = (Spinner) v.findViewById(R.id.mySpinner);

    ArrayAdapter<CharSequence> adapter = 
            ArrayAdapter.createFromResource(
                    getActivity(),
                    R.array.options, 
                    R.layout.spinner_item);     
    adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
    spinner.setAdapter(adapter);

    spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, 
                                   int position, long id) 
        {
            switch (position)
            {
            case 0: 
                // This works fine:
                TextView tv = (TextView)
                    spinner.findViewById(android.R.id.text1);
                tv.setText("TEST");
                break;
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) 
        {

        }           
    });

    // tv is always null on the line below
    TextView tv = (TextView) spinner.findViewById(android.R.id.text1);
    tv.setText("TEST");

    return v;
}

The Spinner itself is not null. It's tv that is null.

Does anyone know why I can't get a reference to the Spinner's TextView here, and how I could get such a reference?

EDIT:

I solved it by adding an OnGlobalLayoutListener to the spinner's ViewTreeObserver:

spinner.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() 
            {
                spinner.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                TextView tv = (TextView) spinner.findViewById(android.R.id.text1);  
                tv.setText("TEST");
            }
        });

Upvotes: 0

Views: 374

Answers (2)

MHP
MHP

Reputation: 2731

put this in onWindowFocusChange()

TextView tv = (TextView) spinner.findViewById(android.R.id.text1);
tv.setText("TEST");

Upvotes: 0

yogurtearl
yogurtearl

Reputation: 3065

The views in Spinner get created as part of the layout pass which will happen on a future iteration of the main message queue. You are trying to access the View before it is created, findViewById is returning null.

This will put the update on the main queue, so it occurs after layout.

    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            TextView tv = (TextView) spinner.findViewById(android.R.id.text1);
            tv.setText("TEST");
        }
    });

A better approach might be to have a custom subclass of Spinner, that does what you need ( maybe in onLayout )

Upvotes: 1

Related Questions