Android Application series: ViewHolder tool class implementation worth collecting
Preface
In the process of APP development, the siege lion has to look at the components ListView and GridView, and send a few waves of autumn waves. Naturally, the original ecological beauty BaseAdapter is a programmer's favorite. With it, we can do what we want. Hey, you know, haha ~
However, every time we write a BaseAdapter, we consciously write a ViewHolder for him. One or two of them are fine. In case there are countless ListView entries in the application ~ Your sister! All the same, see all aesthetic fatigue. As the greatest programmer in the 22nd century, taking off and getting online is always our most sincere pursuit. So how can we remove ViewHolder from the BaseAdapter? It is not unnecessary. Instead, it is necessary to build it into a gorgeous tool class, which is the lonely tool class in the income corner.
Implementation of ViewHolder
I think the implementation of ViewHolder should be briefly introduced. Google uses the View reuse idea in the Adapter smartly, naturally, it makes it a little more possible for our silk machine to bring some white-rich applications. The specific implementation of ViewHolder is basically reflected in the BaseAdapter's getView (int position, View convertView, ViewGroup parent) method. See the following code:
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
- if (convertView == null) {
- convertView = inflater.inflate(R.layout.listview_item_layout, parent, false);
- holder = new ViewHolder();
- holder.studentName = (TextView) convertView.findViewById(R.id.student_name);
- holder.studentAge = (TextView) convertView.findViewById(R.id.student_age);
- convertView.setTag(holder);
- }
- else {
- holder = (ViewHolder) convertView.getTag();
- }
- Student data = (Student) getItem(position);
- holder.studentName.setText(data.getName());
- holder.studentAge.setText(data.getAge());
- return convertView;
- }
-
- class ViewHolder {
- public TextView studentName;
- public TextView studentAge;
- }
Obviously, you don't want to ask me where ViewHolder is. If you look up a little, you will see the large class ViewHolder. The ViewHolder usage here mainly involves two aspects: Reuse of convertView, and reuse of indexes in ViewHolder, that is, convertView. If you are not familiar with the specific usage, you can use Baidu. I am sorry for this blog post, because the purpose of writing this code here is definitely not to introduce how you use ViewHolder, I just want to tell you how bloated the traditional ViewHolder method is! And for every new BaseAdapter, You have to implement it over and over again ~
ViewHolder tool class implementation
Naturally, we need to grow small and take actions as early as possible. Since we are bored, we can write it as a Tool class. See the following code
- static class ViewHolder {
- public static <T extends View> T get(View view, int id) {
- SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
- if (viewHolder == null) {
- viewHolder = new SparseArray<View>();
- view.setTag(viewHolder);
- }
- View childView = viewHolder.get(id);
- if (childView == null) {
- childView = view.findViewById(id);
- viewHolder.put(id, childView);
- }
- return (T) childView;
- }
- }
This is the implementation of the tool class. Let's talk a little bit about the implementation principle:
1. ViewHolder is stored in a SparseArray because it depends on the View Tag.
2. Check whether the Tag in the View exists in viewHolder. If no, ask her to generate one.
3. Search for the View index in viewholder, that is, SparseArray. If not, use findViewById to put it and return it. if it already exists, it is a pleasure to use it directly.
Paste the code used in the BaseAdapter:
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = inflater.inflate(R.layout.listview_item_layout, parent, false);
- }
- TextView name = Tools.ViewHolder.get(convertView, R.id.student_name);
- TextView age = Tools.ViewHolder.get(convertView, R.id.student_age);
-
- Student data = (Student) getItem(position);
- name.setText(data.getName());
- age.setText(data.getAge());
-
- return convertView;
- }
Concise and clear, not to mention ~~~ Hey, if you want to write ViewHolder later, you can directly call the Tools tool class to save your mind ..
Analysis feasibility
To use this tool as a tool class, we need to evaluate the value of this tool first.
In general, we can evaluate the usability from the following aspects? Memory leakage? Performance improvement? Robustness? And so on ......
Ease of use: the biggest feature of the tool class is ease of use and simplicity. This ViewHolder is a typical method to use it. We don't have to worry about writing some adaptive code and directly pass in the View and id, high Cohesion and loose coupling. In addition, the <T extends View> T generic template method is used to automatically adapt to the external View subclass. We do not need to manually force the change.
Memory leakage: Some beginners stubbornly think that the SparseArray <View> viewHolder variable will cause memory leakage when they see the static method, but java tells us that, the small life of this variable is only in the method execution. After the method is completed, GC is recycled. ViewHolder is always placed in the View Tag. Once the View is recycled, ViewHolder disappears naturally. Don't believe it. Open DDMS and use your 28-Year-Old user's hand to Keep refreshing listView. This ensures that the object is basically stable in one value.
Performance Improvement: here we found that the SparseArray set is used instead of HashMap. We know that SparseArray is a tool class of Android and is a class officially recommended to replace HashMap <Integer, E>, it uses binary search internally to improve the search efficiency, and it is not a matter of two. Who knows? For details, you can du nianggu or turn left source code.
Therefore, as a tool class, it is completely qualified. Copy it to your tools and util, and then we can use ViewHolder happily and elegantly ..