Android about getItemViewType and getViewTypeCount in ListView

When customizing the ListView in Android, there is often such a requirement: to display two or more different items in the same ListView. For example, one type of item displays only one TextView, while another type of item displays a TextView plus an ImageView. This requirement is very common.

To achieve this effect, we will use the two functions mentioned in the title, getItemViewType and getViewTypeCount.

So, what is the role of these two functions? What is the relationship between them?

The first is the role of these two functions. The role of getItemViewType is to return an integer. We can understand that this integer is the type of return. For example, we can define the type of an Item that contains only one TextView as 0, which contains a TextView. The type of an ImageView Item is defined as 1 (how to define it is completely up to you), this function will receive an int type position parameter, this is actually the position of the ListView display item, we can return different types according to different positions (For example, when position is a singular number, it returns 0, and when position is a double number, it returns 1)

So, what is the use of the different types returned?

very useful! We cross-display different items in the ListView, mainly relying on the return value of this function. The specific approach is: we can get the returned type value in the getView method, and then judge according to the type value, fill in different xml layout files with different type values, and then return the filled layout file, so that the The purpose of displaying multiple items in a ListView)

Okay, now the function of getItemViewType is basically finished. In fact, the usage is very simple. But there is a trap when using this function, that is, when rewriting this function (this function is inherited from the parent class by BaseAdapter), we must also rewrite the getViewTypeCount function.

Then some students will ask, what if the function getViewTypeCount is not rewritten?

The answer is, an error will be reported! The following are the errors reported when my program does not rewrite this function:

 20701-20701/exercise.viewpager.me.listviewforscrollviewstudy E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.ClassCastException: exercise.viewpager.me.listviewforscrollviewstudy.MainActivity$ViewHolder1 cannot be cast to exercise.viewpager.me.listviewforscrollviewstudy.MainActivity$ViewHolder2
            at exercise.viewpager.me.listviewforscrollviewstudy.MainActivity$MyAdapter.getView(MainActivity.java:125)
            at android.widget.AbsListView.obtainView(AbsListView.java:2161)
            at android.widget.ListView.measureHeightOfChildren(ListView.java:1247)

......

The following logs have no value, so I won’t paste them one by one. You will see that the error reported is very strange, it tells us that the type conversion is abnormal.

Well, if we rewrite this method, if we rewrite it directly, we will find that this method defaults to this:

 @Override
        public int getViewTypeCount() {
            return super.getViewTypeCount();
        }
You probably thought that it would be enough to rewrite it in this way, and then everyone was very wrong. The result obtained by rewriting this method is the same as not writing this function, or a type conversion error is reported. (I will finally share the code of my experiment with you, interested students can download and take a look, but my code is a project written in AndroidStudio, and students who use Eclipse may need to build a project by themselves and paste the code used for the experiment. With the layout)

So the question is, since it reports an error if you don't write this function, and the same error is reported if you copy it directly, then what kind of value should we return in this function?

The answer is: we need to return a value that is the same as or greater than the number of types we need.

For example, if we now need to make the ListView display two different items, then we need to return 2, or an integer greater than 2. (Generally it will return 2, because returning an integer greater than 2 has no practical meaning)

And there is one more thing to pay attention to , because it is very hidden and cheating, that is, in addition to returning the number of Item types that are greater than or equal to what we need, the Type we need to return is a continuous integer starting from 0.

If you don’t do this, the following error will be reported (for example, we return 2 in getViewTypeCount, but the value of our type is defined as 1, and then the following error will be reported)

 22928-22928/exercise.viewpager.me.listviewforscrollviewstudy E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.ArrayIndexOutOfBoundsException: length=3; index=3
            at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6424)
            at android.widget.ListView.measureHeightOfChildren(ListView.java:1259)
            at android.widget.ListView.onMeasure(ListView.java:1159)

.......(Remaining omitted)

As you can see, what was reported at this time was an array out-of-bounds error. This error was really cheating, and the chance was no clue. I was stuck with this error for a day. Because of how to check the code and how to think, I don't know where I am wrong, because the subscript of the array out of bounds is 3, but the number of types defined by myself is also 3. There is no possibility of out of bounds. After investigation, it was discovered that it was because the type did not increase from 0.

After changing the type to 0,1, everything is normal.

Well, there are only so many things to share, not much knowledge, but if you don’t know it, it’s enough for a long time.

If you want to know more details, you can go to Baidu to search for the usage of these two functions. Some information is still very enlightening.

Finally, to summarize, the usage of these two functions should be noted:

1. The two functions getItemViewType and getViewTypeCount must be used in combination.

2. When we specify the value of type, we should start from 0 and increase in order. Don't jump to define the value of type, because it may cause array out of bounds or null pointer errors.

3. The value returned in getViewTypeCount must be greater than or equal to the number of type (provided that you define the value of type continuously from 0)

4. If you jump to define the value of type, a null pointer exception will occur (reported on the ListView class). If you continuously define the type value, but do not start from 0, and you return the real number of type, the array will be out of bounds. abnormal. (For example, if type is defined as 1, 2, 3, getViewTypeCount returns 3, which means that the array is out of bounds)

5. The final conclusion is: 1) Continuously define the value of type starting from 0. 2) In the getViewTypeCount function, the number of defined types is returned. As long as these two items are followed, there will be no problems. You can achieve the effect of displaying different types of Item in a ListView.

Finally, I sent my own experimental code: (The uploaded code can run correctly. You can modify different values ​​according to the instructions in this article to verify what kind of errors will occur in various situations.) By the way, if we make a mistake when judging the value of type in getView, a null pointer exception may also occur (for example, the type is 0,1,2 but the value of your switch type is written as 1, 2, 3) Okay, no more wordy, the following is the address of the code, interested students can download and experiment~

http://download.csdn.net/detail/awy1988/8543367


Guess you like

Origin blog.csdn.net/awy1988/article/details/44708579