Reputation: 4927
My questions are:
Upvotes: 107
Views: 137578
Reputation: 1730
getView()
method in Adapter is for generating item's view of a ListView
, Gallery
,...
LayoutInflater
is used to get the View object which you define in a layout xml (the root object, normally a LinearLayout
,
FrameLayout
, or RelativeLayout
)
convertView
is for recycling. Let's say you have a listview which can only display 10 items at a time, and currently it is
displaying item 1 -> item 10. When you scroll down one item, the
item 1 will be out of screen, and item 11 will be displayed. To
generate View for item 11, the getView()
method will be called, and
convertView
here is the view of item 1 (which is not necessary
anymore). So instead create a new View object for item 11 (which is
costly), why not re-use convertView
? => we just check convertView
is
null or not, if null create new view, else re-use convertView
.
parentView
is the ListView or Gallery... which contains the item's view which getView()
generates.
Note: you don't call this method directly, just need to implement it to tell the parent view how to generate the item's view.
Upvotes: 74
Reputation: 495
If you want pass a view to a function (as argument) you can define an element first, for example a frame layout:
FrameLayout frameLayout = findViewById(R.id.frame_layout);
then get view of the element:
frameLayout.getRootView();
Upvotes: 0
Reputation: 375
You can also find useful information about getView at the Adapter interface in Adapter.java file. It says;
/**
* Get a View that displays the data at the specified position in the data set. You can either
* create a View manually or inflate it from an XML layout file. When the View is inflated, the
* parent View (GridView, ListView...) will apply default layout parameters unless you use
* {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
* to specify a root view and to prevent attachment to the root.
*
* @param position The position of the item within the adapter's data set of the item whose view
* we want.
* @param convertView The old view to reuse, if possible. Note: You should check that this view
* is non-null and of an appropriate type before using. If it is not possible to convert
* this view to display the correct data, this method can create a new view.
* Heterogeneous lists can specify their number of view types, so that this View is
* always of the right type (see {@link #getViewTypeCount()} and
* {@link #getItemViewType(int)}).
* @param parent The parent that this view will eventually be attached to
* @return A View corresponding to the data at the specified position.
*/
View getView(int position, View convertView, ViewGroup parent);
Upvotes: 0
Reputation: 31846
1: The LayoutInflater
takes your layout XML-files and creates different View-objects from its contents.
2: The adapters are built to reuse Views, when a View is scrolled so that is no longer visible, it can be used for one of the new Views appearing. This reused View is the convertView
. If this is null it means that there is no recycled View and we have to create a new one, otherwise we should use it to avoid creating a new.
3: The parent
is provided so you can inflate your view into that for proper layout parameters.
All these together can be used to effectively create the view that will appear in your list (or other view that takes an adapter):
public View getView(int position, @Nullable View convertView, ViewGroup parent){
if (convertView == null) {
//We must create a View:
convertView = inflater.inflate(R.layout.my_list_item, parent, false);
}
//Here we can do changes to the convertView, such as set a text on a TextView
//or an image on an ImageView.
return convertView;
}
Notice the use of the LayoutInflater
, that parent
can be used as an argument for it, and how convertView
is reused.
Upvotes: 120
Reputation: 7634
LayoutInflater
is used to generate dynamic views of the XML for the ListView
item or in onCreateView
of the fragment.
ConvertView
is basically used to recycle the views which are not in the view currently. Say you have a scrollable ListView
. On scrolling down or up, the convertView
gives the view which was scrolled. This reusage saves memory.
The parent parameter of the getView()
method gives a reference to the parent layout which has the listView. Say you want to get the Id of any item in the parent XML you can use:
ViewParent nv = parent.getParent();
while (nv != null) {
if (View.class.isInstance(nv)) {
final View button = ((View) nv).findViewById(R.id.remove);
if (button != null) {
// FOUND IT!
// do something, then break;
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d("Remove", "Remove clicked");
((Button) button).setText("Hi");
}
});
}
break;
}
}
Upvotes: 2
Reputation: 13562
What is exactly the function of the LayoutInflater?
When you design using XML, all your UI elements are just tags and parameters. Before you can use these UI elements, (eg a TextView or LinearLayout), you need to create the actual objects corresponding to these xml elements. That is what the inflater is for. The inflater, uses these tags and their corresponding parameters to create the actual objects and set all the parameters. After this you can get a reference to the UI element using findViewById().
Why do all the articles that I've read check if convertview is null or not first? What does it mean when it is null and what does it mean when it isn't?
This is an interesting one. You see, getView() is called everytime an item in the list is drawn. Now, before the item can be drawn, it has to be created. Now convertView basically is the last used view to draw an item. In getView() you inflate the xml first and then use findByViewID() to get the various UI elements of the listitem. When we check for (convertView == null) what we do is check that if a view is null(for the first item) then create it, else, if it already exists, reuse it, no need to go through the inflate process again. Makes it a lot more efficient.
You must also have come across a concept of ViewHolder in getView(). This makes the list more efficient. What we do is create a viewholder and store the reference to all the UI elements that we got after inflating. This way, we can avoid calling the numerous findByViewId() and save on a lot of time. This ViewHolder is created in the (convertView == null) condition and is stored in the convertView using setTag(). In the else loop we just obtain it back using getView() and reuse it.
What is the parent parameter that this method accepts?
The parent is a ViewGroup to which your view created by getView() is finally attached. Now in your case this would be the ListView.
Hope this helps :)
Upvotes: 5
Reputation: 1277
getView()
method create new View
or ViewGroup
for each row of Listview
or Spinner . You can define this View
or ViewGroup
in a Layout XML
file in res/layout
folder and can give the reference it to Adapter
class Object.
if you have 4 item in a Array passed to Adapter. getView()
method will create 4 View for 4 rows of Adaper.
LayoutInflater class has a Method inflate() whic create View Object from XML resource layout.
Upvotes: 1
Reputation: 13501
Layout inflator inflates/adds external XML to your current view.
getView() is called numerous times including when scrolled. So if it already has view inflated we don't wanna do it again since inflating is a costly process.. thats why we check if its null and then inflate it.
The parent view is single cell of your List..
Upvotes: 4
Reputation: 1243
You could have a look at this video about the list view. Its from last years Google IO and still the best walk-through on list views in my mind.
http://www.youtube.com/watch?v=wDBM6wVEO70
It inflates layouts (the xml files on your res/layout/ folder) into java Objects such as LinearLayout and other views.
Look at the video, will get you up to date with whats the use of the convert view, basically its a recycled view waiting to be reused by you, to avoid creating a new object and slowing down the scrolling of your list.
Allows you to reference you list-view from the adapter.
Upvotes: 8