You can use this statement 100 times: the adapter is used to bind data to each display control on the entry interface.
--------------------------------- Split line -------------------------------------
1. The getview () method encountered an exception in type conversion when customizing the Adapter.
@ Override
Public View getView (int position, View convertView, ViewGroup parent ){
ImageView imageView = new ImageView (mContext );
ImageView. setLayoutParams (new GridView. LayoutParams (120,120 ));
ImageView. setImageResource (data [position]);
ImageView. setScaleType (ScaleType. CENTER );
Return imageView;
}
The red part uses the GridView (if you use the GridView ). you cannot directly import the package to the LayoutParams of the ViewGroup. in this way, no errors will be reported during compilation, but this silly x error is reported during runtime. lang. classCastException: android. view. viewGroup $ LayoutParams.
2. What are the functions of the convertView parameter in getView?
Solve the Problem of ListView scrolling card
I wrote a GridView similar to the following. There is a card or a hop when scrolling, especially when there are many records.
The working principle of the GridView and ListView mechanisms is similar. They are based on ListAdapter to process View control. When troubleshooting the problem, we also tested replacing the GridView with ListView. the problem persists.
The implementation example is roughly like this:
There are about 600 pieces of test data. However, even if it is reduced to about 40, it will be stuck. Monitor the dalvik log in the ddms log, there will be a lot of the following information:
01-14 10:37:47. 579: DEBUG/dalvikvm (13626): GC_EXTERNAL_ALLOC freed 58 objects/2072 bytes in 37 ms
Basically, more than 10 entries will be generated each time a scroll occurs. This is the main cause of the card. That is to say, to release a large number of temporary objects.
These temporary objects are not created by myself. I have loaded the result set to the memory at one time. This is not because of image display. I have removed the image.
In addition, we have also considered the method of expanding the heap memory, but it is not the right remedy, because the memory does not reach the heap upper limit, resulting in full gc. The heap logs can be filtered out by dalvikvm-heap. If the heap memory is full gc, logs similar to this will be generated:
Dalvikvm-heap (11651): Heap Massage needed (768000-byte external allocation too big)
Dalvikvm-heap (11651): Full GC (don't collect SoftReferences)
It can be preliminarily determined that it is the temporary object used by the GridView/ListView to implement scrolling. It is quickly discarded with scrolling, and garbage collection is required, resulting in performance problems.
But why is the address book provided by Android not stuck? There are also nearly 300 records in the address book on my mobile phone. According to the ddms log observation, there are no frequent GC_EXTERNAL_ALLOC logs, and only one or two times of scrolling from the beginning to the end appear.
So I decided to view the source code of the address book. These rows:
@ Override
Public View getView (int position, View convertView, ViewGroup parent ){
......
View v;
If (convertView = null | convertView. getTag () = null ){
NewView = true;
V = newView (mContext, cursor, parent );
} Else {
NewView = false;
V = convertView;
}
The reuse of the ListView Element View is described. Check the api again:
ConvertView The old view to reuse, if possible. note: You shoshould 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.
Therefore, it can be considered that convertView is the cache of elements, because the elements themselves do not change, so it can be judged that if they are not empty, they can be reused. For example, in my example, it is written as follows:
If (convertView = null ){
ConvertView = activity. getLayoutInflater (). inflate (
R. layout. album_grid_element, parent, false );
}
Previously, a new view was created directly each time, and convertView was not reused. This is the root cause of the card.
Another lesson this time is that the solution has not been further resolved from the api layer, that is, the order in which the api can be solved? Do you need to solve it through your own optimization? Whether or not system deployment configurations, such as heap adjustment, are required.
The result is a detour, which consumes time.
You need to read the api documentation first. This issue is based on a simple example of handwriting.
3. rewrote the getview details in BaseAdapter and found the convertView recycle mechanism.
Next, let's talk about some of my problems:
1. What is the meaning of the second parameter in View getview (int position, View convertview, ViewGroup parent;
2. usage of the SetTag and getTag methods of the View;
Solve the first problem first:
In the android SDK, The convertview parameter is described as follows:
The old view to reuse, if possible. Note: You shoshould 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.
Translation:
If possible, this is the reuse of the old View (which cannot be translated into a View. Suggestion: before use, you should check whether the View is not empty or a suitable type.
If this VIew cannot display an appropriate data, this method creates a new View.
If we want to create a ListView, only a few items are displayed on the mobile phone, and the entire ListView may be very long, maybe 100 or even tens of thousands of items, there is always no way for so many items to reside in the memory, so android has prepared a mechanism for you, that is, Recycler. The specific working principle of this mechanism can go to worker. But he hasn't made a clear explanation in some places, so let's talk about it again. First paste the code
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
Android: layout_width = "fill_parent"
Android: layout_height = "fill_parent"
Android: orientation = "vertical">
<ListView
Android: id = "@ + id/result"
Android: layout_width = "fill_parent"
Android: layout_height = "fill_parent"
Android: cacheColorHint = "#00000000">
</ListView>
</LinearLayout>
Note that the value of the android: layout_height attribute of ListView is "fill_paternt". If it is "wrap_content", it will be the adapter code in another case.
Class ListViewAdapter extends BaseAdapter
{
Private Context mContext;
Int I = 0;
Public ListViewAdapter (Context context)
{
This. mContext = context;
}
@ Override
Public int getCount ()
{
Return 30;
}
@ Override
Public Object getItem (int position)
{
Return position;
}
@ Override
Public long getItemId (int position)
{
Return 0;
}
@ Override
Public View getView (int position, View convertView, ViewGroup parent)
{
System. out. println ("getView" + position + "" + convertView); // debug the statement
Holder holder;
If (null = convertView)
{
Holder = new Holder ();
ConvertView = LayoutInflater. from (mContext). inflate (R. layout. textview, null); // mContext indicates the Activtty
Holder. textView = (TextView) convertView. findViewById (R. id. textview );
ConvertView. setTag (holder );
}
Else
{
Holder = (Holder) convertView. getTag ();
}
Holder. textView. setText ("position:" + position );
Return convertView;
}
Class Holder
{
Public TextView textView;
}
}
After running the program, it is found that the convertview of the Item displayed on the screen is empty, and the convetview of the newly generated Item is not empty. So far it is consistent with the above link, but if the android: layout_height attribute value of ListView is set to "wrap_content, it is found that only convertview of the first Item is null, and others are not empty. Although the two settings are different and the results are different, the convertview mechanism is not changed. So far, we can summarize the convertview mechanism, that is, during initial display, the getview method is called every time an item is displayed, but the covertview is empty (because there are no old views). After the display is complete. If the screen is moved, and some items (or views) run out of the screen, if new items need to be generated, the convertview parameter in the getview method called when these items are displayed is not null, but the view (old view) that is removed from the screen ), all we need to do is to fill the items to be displayed in the recycled view (old view). Finally, note that convertview is null, not just the items initially displayed, there are also some items that have been moved into the screen but have not been recycled by the view. In the end, we implemented the Recycler with the handwritten code ). the second problem should be nested in the first one, But I separated it for clarity: The setTag and getTag methods of view are actually very simple, in actual code writing, a view is not only used to display some strings and images, but sometimes we need them to carry some other data so that we can identify the view or perform other operations. Therefore, android designers created the setTag (Object) method to store some data and bind the view, we can understand that this is a view label or that view stores some data as a container. The data can also be obtained through the getTag () method. At this point, we should have understood the setTag and getTag. Back to the above topic, we use the setTag method and getTag method of convertview to bind the data we want to display to convertview. If convertview is displayed for the first time, we will create a new Holder object and bind it to it. At last, return convertview to display it; if convertview is recycled, we do not need to create a new holder object. We only need to retrieve the original bound holder and add new data. So far, I have finished talking about the problem. Have you solved it?
I have understood a little more about the adapter. A kind of View is called AdapterView. For example, ListView is a kind of AdapterView. This type of View has a setAdapter (Adapter adapter) method to update the View.
Java code
ListView listView = (ListView) findViewById (R. layout. list_view );
ListView. setAdapter (new MyAdapter (this ));
The previous listView has no data during initialization, that is, no ListItem. The data is filled by the setAdapter () method.
The function of the Adapter class is to return a View based on the data source. Each View will eventually become one of the Child views of AdapterView. Like its name, the Adapter is an Adapter for data-to-view. It can be understood as a container processor, which maps each item in the container into a View and returns. The data source can be a data set specified by the resource file, SQLite, or a custom object in the memory ...... In short, it is a collection of data objects. The View to be returned is created and returned by the getView () method in the Adapter. It can be set from the layout file or custom View object.
After figuring out the principles, we can see how AdapterView and Adapter work together to generate pages. The Adapter cyclically calls the getView () method based on the data source to generate a set of View objects. The AdapterView. setAdapter () method then uses the previously generated View object set to generate data items for the View. ListView is only a subclass of AdapterView, and there are many other adapterviews, but the principles are the same. If you have time, you can look at the source code of the getView () method of the ListAdapter class. You should have a clearer understanding of this process.
There is a special introduction to this on Dev Guide: http://developer.android.com/guide/topics/ui/binding.html
You can also see what its subclass has in the end: http://developer.android.com/reference/android/widget/AdapterView.html
After clarifying the previous point, let's look at ListActivity. In fact, ListActivity is just a common Activity, but it has a built-in ListView and provides the getListView () method to obtain the built-in ListView; the setListAdapter () method is also provided to set the Adapter for the built-in ListView, as well as methods such as onListItemClick. To use ListActivity, you can use a common Activity. You only need to write more methods.