In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-03 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
How to carry out Adapter in-depth understanding and optimization, I believe that many inexperienced people do not know what to do, so this paper summarizes the causes of the problem and solutions, through this article I hope you can solve this problem.
Generally, we set an Adapter for a View that contains multiple elements, such as ListView,GridView,ExpandableListview. Adapter is a bridge to provide data with View, as well as a view bridge to provide each Item.
Take ListView as an example, its working principle is:
● ListView for each item in List, adapter calls a getView method to get the layout view
● We usually Inflate a new View, populate the data and return the display
Of course, if we have a lot of Item (for example, tens of thousands), will we build a new View? Obviously, this kind of memory is unacceptable, and Google won't do it either. there is a component called Recycler in Android, and here's how it works:
Obviously, no matter how many item there are in the data, the Recycler only stores the visible View in memory on the display. When sliding down, the top invisible Item moves directly back below to repopulate the data to become a new item. So you don't have to create a new View every time.
This is the call to the getView method that we often see in Adapter. Corresponding to this method, we can see that convertView is the layout view of each Item before Recyler.
Public View getView (int position, View convertView, ViewGrouppare
So, Android has provided us with a Recycler mechanism, so we should take advantage of this mechanism instead of going to inflate a View every time.
Example
Don't
Public View getView (int position, View convertView, ViewGroupparent) {convertView = LayoutInflater.from (mContext) .comparate (R.layout.itemviewjnulls); / / dosomething... Return converView;}
Do
Public View getView (int position, View convertView, ViewGroupparent) {if (convertView = = null) {convertView = LayoutInflater.from (mContext) .propagate (R.layout.item_view, null);} / / dosomething... Return converView;}
The role of ViewHolder
The Recycler mode mentioned earlier is to solve the waste of View resources caused by repeated inflate, is there any way to optimize our performance again? The answer is Yes.
We still look at it from every method call in getView and find that when we get the convertView, we go to findViewById according to this layout every time. As follows, let's write in the usual way:
FindViewById is parsing the sub-View of the layout.xml layout, and parsing xml is a strenuous task, so Google also suggests that we optimize this thankless work, so we put forward the concept of ViewHolder.
That is, use a static class to save the reference relationships of each child View in the xml, so that it is not necessary to parse the xml every time. As follows: it is a ViewHolder written for the above code
If (convertView = = null) {convertView = mInflater.inflate (R.layout.item_view, null);} TextView titleTextView = (TextView) convertView.findViewById (R.id.text); ImageView iconImageView = (ImageView) convertView.findViewButId (R.id.icon)); / / DoSomething …
FindViewById is parsing the sub-View of the layout.xml layout, and parsing xml is a strenuous task, so Google also suggests that we optimize this thankless work, so we put forward the concept of ViewHolder.
That is, use a static class to save the reference relationships of each child View in the xml, so that it is not necessary to parse the xml every time. As follows: it is a ViewHolder written for the above code
Static class ViewHolder {TextView titleTextView; ImageView iconImageView;}
However, in the getView method, we can only get three parameters, position, convertView, viewGroup can not get our custom ViewHolder. So, if we want to get ViewHolder through convertView, we can only put it in tag.
Here is a complete ViewHolder using exmaple:
Public View getView (int position, View convertView, ViewGroup parent) {ViewHolder holder; if (convertView = = null) {convertView = mInflater.inflate (R.layout.item_view, null); holder = new ViewHolder (); holder.titleTextView = (TextView) convertView.findViewById (R.id.text); holder.iconImageView = (ImageView) convertView.findViewById (R.id.icon); convertView.setTag (holder) } else {holder = (ViewHolder) convertView.getTag ();} holder.titleTextView.setText (data [pos] .title); holder.iconImageView.setImageBitmap (data [pos] .bitmap); return convertView;} static class ViewHolder {TextView titleTextView; ImageView iconImageView;}
Tips. RecyclerView in Support.v7 is made with this idea.
Multiple types of ViewType
When we call the method getView in Adapter, if the Item View in the entire list has multiple types of layouts, such as:
It doesn't seem feasible for us to continue to use convertView to repopulate the data, because the convertView type returned each time is different and cannot be reused.
Android also thought of this when he was designing. So, there are two methods reserved in adapter.
Public int getItemViewType (int position)
Public int getViewTypeCount ()
Just revisit these two methods, set the number of ItemViewType and the judgment method, and Recycler can selectively give different convertView.
Example:
@ Override public intgetItemViewType (int position) {if (data [pos] .type = = 0) {return 0;} else {return 1;} @ Override public int getViewTypeCount () {return 2;} @ Override public View getView (int position, View convertView, ViewGroup arg2) {TitleViewHolder titleHolder; InfoViewHolder infoHolder; int type = getItemViewType (position) If (convertView = = null) {switch (type) {case 0: convertView = mInflater.inflate (R.layout.item_view, null); titleHolder = new TitleViewHolder (); titleHolder.titleTextView = (TextView) convertView.findViewById (R.id.text); titleHolder.iconImageView = (ImageView) convertView.findViewById (R.id.icon) ConvertView.setTag (titleHolder); break; case 1: convertView = mInflater.inflate (R.layout.item_view2, null); infoHolder = new InfoViewHolder (); infoHolder.titleTextView = (TextView) convertView.findViewById (R.id.text); convertView.setTag (infoHolder); break }} else {switch (type) {case 0: titleHolder = (TitleViewHolder) convertView.getTag (); break; case 1: infoHolder = (InfoViewHolder) convertView.getTag (); break } switch (type) {case 0: titleHolder.titleTextView.setText (Data [pos] .title); break; case 1: infoHolder.titleTextView.setText (Data [pos] .title); infoHolder.iconImageView.setImageBitmap (Data [pos] .bitmap); break;} return convertView } static class TitleViewHolder {public ImageView iconImageView; public TextView titleTextView;} static class InfoViewHolder {TextView titleTextView; ImageView iconImageView;}
NotifyDataSetChanged refresh mechanism
When the data in ListView changes and we want to refresh the View in ListView, we usually call NotifyDataSetChanged to refresh the ListView. Look at its source code:
Public void notifyChanged () {synchronized (mObservers) {/ / send onChanged for to each sub-View (int I = mObservers.size ()-1; I > = 0; iMub -) {mObservers.get (I). OnChanged ();}
It is shown that it has been refreshed for each sub-View, of course, if our data are all variables can be understood. However, in general, there are not many View that we need to update. The NotifyDataSetChanged method is called frequently and it is not appropriate to refresh the entire interface. This will redraw all the item displayed on the interface, even if only one view has changed.
So, we can write a method of update to refresh a View separately.
Private void updateView (int itemIndex) {intvisiblePosition = yourListView.getFirstVisiblePosition (); Viewv = yourListView.getChildAt (itemIndex-visiblePosition); ViewHolder viewHolder = (ViewHolder) v.getTag (); if (viewHolder = null) {viewHolder.titleTextView.setText ("I updated");}}
Optimization of Network Picture in Adapter
Every Item in ListView will bring network pictures. When there are too many item, too many network requests and too much picture storage will slow down the ListView card.
So make some optimizations for it:
● uses thread pool for network picture request, and uses local cache processing (LRUCache) after network picture request is obtained, memory + local file cache. Of course, to prevent memory overflow and untimely recycling, you need to use weak references (WeakReference) to store pictures in memory.
● scales the images taken from the network proportionally to reduce memory consumption.
There is no need to request a web image when ● slides. Because network requests are generally time-consuming, if the image of an Item is replaced by Recycler when the request comes, the picture will not correspond to the Item.
Tips. Most of the tools for network requests are inconvenient to cite examples, but the more frequently used tool class for network picture requests is Volley. Volley provides a tool class for ImageLoader and NetworkImageView's View for network picture requests.
After reading the above, have you mastered the methods of in-depth understanding and optimization of Adapter? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 212
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.