Recently optimized the list display in the project, by the way, the use of RecyclerView to do the packaging, the purpose is when the list of demand is more complex, still can keep the logic clear and decoupled, at the same time through the packaging to make the performance of the complex list to get a certain guarantee.

Of course, if it is a very simple list, in fact, Android native RecyclerView plus Adapter has been more convenient, there is no need to do excessive packaging.

GitHub: github.com/zhengcx/Ins…

Every refactoring or repackaging of a project is a result of dissatisfaction with the status quo, so let’s start this blog post by looking at the problems that the repackaging project solved.

1. Resolve repeated global refresh

Need to pay attention to the use of list in your project, especially whether are repeated load more global refresh, it greatly influenced the performance of complex of the list, you need to consider every time refresh to refresh the don’t need to refresh the item, one is on performance will be improved, another page on the user experience will be a lot better, This project provides methods for global and incremental refreshes to ensure that more items are loaded or that a single item is only refreshed locally.

2. Solve the efficiency of adding and deleting headers/footers

RecyclerView itself does not provide a convenient way to add headers/footers like ListView, so we need to do it ourselves.

There are two main types on the web: one is to use wrap to distinguish header and footer from normal item, and the other is to treat header and footer as itemType.

We use the second method, which provides a convenient way to add headers/footers. Of course, if we treat header/footer as an itemType, the addition or deletion of header/footer (especially headers) will refresh the list globally. There is only one header for RecyclerView, is a ViewGroup, and then to add or delete one or more headers, are just to add or delete the View in the ViewGroup, will not refresh the whole list, to provide performance and experience.

3. Solve the problem of code not being clear when the list has multiple ItemTypes

When your list has multiple complex ItemTypes, it’s easy for the Adapter code to get confused and not clear enough to expand. Our purpose of encapsulation is to:

1. Delegate the processing logic of each itemType to its own itemDelegate to decouple the processing logic of different Itemtypes

2. Make the code easy to expand, that is, no matter how many itemTypes to add in the future, it can be very clear, very convenient.

In the project, the DelegateScheduler is used to manage the processing logic of different Itemtypes, so that the multiple ItemTypes become clear and easy to expand.

4. Solve the problem of overdrawing due to state View

Our list usually requires several views that show the loading state, such as loadingView, loadfailed View, and loadempty View. If you start with these views in your layout file and control them by setting whether or not they are visible, this can cause problems with the nested layout transition. You can also use the ViewStub to optimize this, but this may not happen even if the View state is inflated once.

If you think of these state views as an itemType, and have them participate in the collection, participate in the cache just like a normal item, would you solve this problem? That’s the ideal way I’ve seen it so far, but there may be better ways.

5. Solve more problems with pull-up loading

Obviously if you put the pull up load more this function in your business code to listen is not appropriate, we need to encapsulate, let recyclerView automatically with this function, directly used on it.

This project provides two different listening methods for pull-up loading, depending on personal preference.

1. Real-time monitoring, that is to say, as long as the user slides, then it will real-time monitoring to judge whether to start loading the next page data, this kind of advantage is to make the list preloading more real-time, basically real-time users can continue to pull down, the user can not perceive our loading process.

2. The other is that the judgment of whether to load the next page data will be initiated only when the scrolling state of the list changes. In this case, the user will initiate the loading of the next page when the user slides to stop.

Of course, you can set the parameter of how many items to preload the next page in both ways. The default is the second way, and the first way can be set to use.

6. Resolve the issue of repeated binding of click events on item

RecyclerView doesn’t provide the same setOnItemCLickListener() method that ListView does to bind the item’s click event, so we usually set the item’s click event ourselves, which makes it easy to set the click event multiple times.

This encapsulates the setOnItemClickListener() method so that you can safely set the item click event, and provides the data bound to the item in the callback, as well as important information such as the position of the item and the type of the item. This allows you to do all kinds of things correctly in the click event in a list of multiple itemtypes.

Suggestions for list performance problems

For complex lists, performance issues are particularly important. One is to try to do local refreshes rather than full refreshes, and the other is to try to minimize overdrawing. It is also very important to pay attention to the logic of your bindViewHolder() in each version to see if there are time-consuming methods or operations in the logic of your list. With SysTrace+TraceView, you can quickly identify time-consuming methods and performance bottlenecks, and then optimize them accordingly.

GitHub: github.com/zhengcx/Ins…

Finally, let’s hope every list in the world is as smooth as a thread