Android 创建您自己的自定义适配器时 getView() 方法如何工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10120119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does the getView() method work when creating your own custom adapter?
提问by GrowinMan
My questions are:
我的问题是:
- What is exactly the function of the LayoutInflater?
- 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?
- What is the parent parameter that this method accepts?
- LayoutInflater 的功能究竟是什么?
- 为什么我读过的所有文章都会先检查 convertview 是否为空?当它为空时是什么意思,当它不是时又是什么意思?
- 这个方法接受的父参数是什么?
回答by Jave
1: The LayoutInflater
takes your layout XML-files and creates different View-objects from its contents.
1:LayoutInflater
获取您的布局 XML 文件并从其内容创建不同的视图对象。
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.
2:适配器是为了重用视图而构建的,当视图滚动到不再可见时,它可以用于出现的新视图之一。这个重用的视图是convertView
. 如果这是 null 则意味着没有回收的 View,我们必须创建一个新的 View,否则我们应该使用它来避免创建一个新的。
3: The parent
is provided so you can inflate your view into that for proper layout parameters.
3:parent
提供了这样你可以将你的视图膨胀到适当的布局参数中。
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.
请注意 , 的使用LayoutInflater
,parent
可以用作它的参数,以及如何convertView
重用。
回答by Anh Tuan
getView()
method in Adapter is for generating item's view of a ListView
, Gallery
,...
getView()
Adapter 中的方法用于生成项目的视图 a ListView
, Gallery
,...
LayoutInflater
is used to get the View object which you define in a layout xml (the root object, normally aLinearLayout
,FrameLayout
, orRelativeLayout
)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, andconvertView
here is the view of item 1 (which is not neccessary anymore). So instead create a new View object for item 11 (which is costly), why not re-useconvertView
? => we just checkconvertView
is null or not, if null create new view, else re-useconvertView
.parentView
is the ListView or Gallery... which contains the item's view whichgetView()
generates.
LayoutInflater
用于获取您在布局中的XML定义视图对象(根对象,通常是一个LinearLayout
,FrameLayout
或RelativeLayout
)convertView
是为了回收。假设你有一个列表视图,它一次只能显示 10 个项目,目前它正在显示项目 1 -> 项目 10。当你向下滚动一个项目时,项目 1 将在屏幕外,项目 11 将显示. 要为第 11 项生成视图,将调用 getView() 方法,convertView
这里是第 1 项的视图(不再需要)。因此,改为为 item 11 创建一个新的 View 对象(这很昂贵),为什么不重用convertView
呢?=> 我们只是检查是否convertView
为空,如果为空则创建新视图,否则重新使用convertView
。parentView
是 ListView 或 Gallery...,其中包含getView()
生成的项目视图。
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.
注意:你不直接调用这个方法,只需要实现它来告诉父视图如何生成项目的视图。
回答by erbsman
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.
你可以看看这个关于列表视图的视频。它来自去年的 Google IO,并且仍然是我心目中最好的列表视图演练。
http://www.youtube.com/watch?v=wDBM6wVEO70
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.
它将布局(在 res/layout/ 文件夹中的 xml 文件)膨胀为 Java 对象,例如 LinearLayout 和其他视图。
观看视频,将让您了解转换视图的最新用途,基本上它是一个等待您重用的回收视图,以避免创建新对象并减慢列表的滚动速度。
允许您从适配器引用您的列表视图。
回答by Shubhayu
What is exactly the function of the LayoutInflater?
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().
当您使用 XML 进行设计时,您的所有 UI 元素都只是标签和参数。在您可以使用这些 UI 元素(例如 TextView 或 LinearLayout)之前,您需要创建与这些 xml 元素对应的实际对象。这就是充气机的用途。充气机使用这些标签及其相应的参数来创建实际对象并设置所有参数。在此之后,您可以使用 findViewById() 获取对 UI 元素的引用。
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?
为什么我读过的所有文章都会先检查 convertview 是否为空?当它为空时是什么意思,当它不是时又是什么意思?
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.
这是一个有趣的。您会看到,每次绘制列表中的项目时都会调用 getView()。现在,在绘制项目之前,必须先创建它。现在 convertView 基本上是最后使用的视图来绘制项目。在 getView() 中,您首先对 xml 进行膨胀,然后使用 findByViewID() 来获取列表项的各种 UI 元素。当我们检查 (convertView == null) 时,我们所做的是检查视图是否为空(对于第一项)然后创建它,否则,如果它已经存在,则重用它,无需再次经历膨胀过程. 使它更有效率。
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.
在 getView() 中你一定也遇到过 ViewHolder 的概念。这使得列表更有效。我们要做的是创建一个viewholder并存储对我们在膨胀后获得的所有UI元素的引用。这样,我们可以避免调用大量的 findByViewId() 并节省大量时间。此 ViewHolder 在 (convertView == null) 条件下创建,并使用 setTag() 存储在 convertView 中。在 else 循环中,我们只是使用 getView() 取回它并重用它。
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.
父级是一个 ViewGroup,由 getView() 创建的视图最终附加到该视图组。现在,在您的情况下,这将是 ListView。
Hope this helps :)
希望这可以帮助 :)
回答by ngesh
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..
Layout inflator 将外部 XML 膨胀/添加到您当前的视图中。
getView() 被多次调用,包括滚动时。所以如果它已经有视图膨胀,我们不想再做一次,因为膨胀是一个昂贵的过程..这就是为什么我们检查它是否为空然后膨胀它。
父视图是列表的单个单元格..
回答by user936414
LayoutInflater
is used to generate dynamic views of the XML for the ListView
item or in onCreateView
of the fragment.
LayoutInflater
用于为ListView
项目或onCreateView
片段生成 XML 的动态视图。
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.
ConvertView
主要用于回收当前不在视图中的视图。假设您有一个可滚动的ListView
. 向下或向上滚动时,会convertView
给出滚动的视图。这种重用可以节省内存。
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:
该getView()
方法的 parent 参数提供对具有 listView 的父布局的引用。假设您想获取可以使用的父 XML 中任何项目的 Id:
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;
}
}
回答by Ravi1187342
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.
getView()
方法来创建新的View
或ViewGroup
为每行Listview
或微调。您可以定义它View
或ViewGroup
在Layout XML
文件res/layout
夹中的文件中定义它,并且可以将其引用给Adapter
类 Object。
if you have 4 item in a Array passed to Adapter. getView()
method will create 4 View for 4 rows of Adaper.
如果数组中有 4 个项目传递给适配器。getView()
方法将为 4 行 Adaper 创建 4 个视图。
LayoutInflater class has a Method inflate() whic create View Object from XML resource layout.
LayoutInflater 类有一个方法 inflate() 从 XML 资源布局创建视图对象。
回答by Hamza Polat
You can also find useful information about getView at the Adapter interface in Adapter.java file. It says;
您还可以在 Adapter.java 文件中的 Adapter 接口中找到有关 getView 的有用信息。它说;
/**
* 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);