Im having a customized ArrayAdapter for a spinner in my app. Here's the code for its getDropDownView() method:
@Override
public View getDropDownView(int position, View convertView,ViewGroup parent) {
View vista = convertView;
if (vista==null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vista = inflater.inflate(R.layout.row_spinner,null);
}
TextView tv = (TextView) vista.findViewById( R.id.textview_entry );
if( !Utils.isSDKAbove( Utils.HONEY_COMB ) )
{
tv.setTextColor( getContext().getResources().getColor( android.R.color.primary_text_light ) );
}
tv.setText( getItem( position ) );
return vista;
}
and when tv.setText(), it throws the NullPointerException for TextView.
However , when I changed the
vista = inflater.inflate(R.layout.row_spinner, null);
to
vista = inflater.inflate(R.layout.row_spinner, parent, false);
it works.
can someone explain a bit more about the difference between the two different signature of the methods?
By declaring a parent root view, you are supplying a parent xml layout for that view. The third boolean parameter then determines whether or not this child view is attached to the parent view. Thereby determining whether child inherits the parent view's touch methods or not.
Either way the view needs to be put into perspective in terms of xml layout, so that the customisations and xml structure you've made will be implemented throughout your view hierarchy.
Using inflate (layout, parent, false)
You are using the parent layout to inflate the view (in this case spinner)
without attaching it to the parent view.
Using null you are not giving the view any layout parameters so the layout parameters for the xml for the textview doesn't exist.
From the docs:
root Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)
attachToRoot Whether the inflated hierarchy should be attached to the root parameter? If false, root is only used to create the correct subclass of LayoutParams for the root view in the XML.
Returns
The root View of the inflated hierarchy. If root was supplied and attachToRoot is true, this is root; otherwise it is the root of the inflated XML file.
Using null is not good way to detach a view from the parent view, unless it is a stand alone feature, like an alert dialog.
The view needs a root view, passing null works some of the time, but only because the program attempts to create default xml parameters for the view.
This article goes into more detail.
So why do you suppose we are given this ViewGroup if we are not supposed to attach to it? It turns out the parent view is a very important part of the inflation process because it is necessary in order to evaluate the LayoutParams declared in the root element of the XML being inflated. Passing nothing here is akin to telling the framework “I don’t know what parent this view will be attached to, sorry.”
The problem with this is android:layout_xxx attributes are always be evaluated in the context of the parent view. As a result, without any known parent, all LayoutParams you declared on the root element of your XML tree will just get thrown away, and then you’ll be left asking “why is the framework ignoring the layout customizations I defined? I’d better check SO and then file a bug.”