Kotlin Primer (22) Simple optimization of the adapter

Source: Internet
Author: User

List view

To implement a variety of views of the permutation class (including but not limited to spinner, ListView, GridView, and so on), Android offers a wide range of adapters for assembling a specification of data, common adapters are: Array Adapter arrayadapter, Simple adapter Simpleadapter, basic adapter Baseadapter, paging adapter Pageradapter. Although the type of adapter is many, but all are not good use, with the array adapter as an example, it and spinner with the implementation of the dropdown box effect, the implementation of code complex, has been criticized. So in the drop-down box a section, simply put arrayadapter together with spinner a brain are discarded, replaced by kotlin extension function selector.
To the list view ListView here, with which the general is the basic adapter baseadapter, this baseadapter is more not simple, based on its list adapter to rewrite several methods, as well as a beginner to the wall of the Viewholder. In short, whenever you want to implement similar news lists, product lists and other pages, the thought of this difficult baseadapter, the heart will be afraid. For example, the description list of the six major planets shown, the icon on the left, the text description on the right, and a very common page.

But this planet list page, if you use Java encoding, you have to write the following long length of code:

public class Planetjavaadapter extends Baseadapter {private Context mcontext;    Private arraylist<planet> mplanetlist;    private int mbackground; Public Planetjavaadapter (context context, arraylist<planet> planet_list, int background) {Mcontext = context        ;        Mplanetlist = planet_list;    Mbackground = background;    } @Override public int getcount () {return mplanetlist.size ();    } @Override public Object getItem (int arg0) {return mplanetlist.get (arg0);    } @Override public long getitemid (int arg0) {return arg0;  } @Override Public View getView (final int position, View Convertview, ViewGroup parent) {Viewholder Holder =        Null            if (Convertview = = null) {holder = new Viewholder ();            Convertview = Layoutinflater.from (Mcontext). Inflate (R.layout.item_list_view, NULL);            Holder.ll_item = (linearlayout) Convertview.findviewbyid (R.id.ll_item); Holder.iV_icon = (ImageView) Convertview.findviewbyid (R.id.iv_icon);            Holder.tv_name = (TextView) Convertview.findviewbyid (r.id.tv_name);            Holder.tv_desc = (TextView) Convertview.findviewbyid (R.ID.TV_DESC);        Convertview.settag (holder);        } else {holder = (Viewholder) convertview.gettag ();        } Planet Planet = Mplanetlist.get (position);        Holder.ll_item.setBackgroundColor (Mbackground);        Holder.iv_icon.setImageResource (Planet.image);        Holder.tv_name.setText (Planet.name);        Holder.tv_desc.setText (PLANET.DESC);    return convertview;        Public final class Viewholder {public LinearLayout ll_item;        Public ImageView Iv_icon;        Public TextView Tv_name;    Public TextView Tv_desc; }}

The above Java implementation of the adapter class Planetjavaadapter, it is really lengthy and obscure, however, this code template is basically a list view standard, as long as the Java code, you must follow the sample drawing scoop. What if this adapter class is implemented with Kotlin? Immediately using Android Studio to convert the above Java code to Kotlin encoding, the converted Kotlin code resembles the following fragment:

Class Planetkotlinadapter (Private Val mcontext:context, private Val mplanetlist:arraylist<planet>, Private Val MB Ackground:int): Baseadapter () {Override Fun GetCount (): Int {return mplanetlist.size} override fun GE TItem (arg0:int): Any {return mplanetlist[arg0]} override fun Getitemid (arg0:int): Long {return AR G0.tolong ()} Override Fun GetView (Position:int, Convertview:view, Parent:viewgroup): view {var view = C        Onvertview var holder:viewholder? if (view = = null) {holder = Viewholder () view = Layoutinflater.from (Mcontext). Inflate (R.layout.item _list_view, null) Holder.ll_item = View.findviewbyid (R.id.ll_item) as linearlayout Holder.iv_icon =            View.findviewbyid (R.id.iv_icon) as ImageView holder.tv_name = View.findviewbyid (r.id.tv_name) as TextView   Holder.tv_desc = View.findviewbyid (R.id.tv_desc) as TextView View.tag = Holder     } else {holder = View.tag as Viewholder} val planet = mplanetlist[position] holder. Ll_item!!. SetBackgroundColor (mbackground) Holder.iv_icon!!. Setimageresource (planet.image) holder.tv_name!!. Text = Planet.name Holder.tv_desc!!.    Text = Planet.desc return view!! } inner class Viewholder {var ll_item:linearlayout? = null var Iv_icon:imageview? = NULL var TV _name:textview? = null var tv_desc:textview? = null}}

By contrast, the biggest improvement in the direct conversion of the Kotlin code is that the constructors and initialization parameters are placed in the first row, and no significant optimizations are made elsewhere. Eye look not much improvement, but because kotlin of empty security mechanism, no more than a few question marks and double exclamation, it is not worth the candle. The problem is that Kotlin requires each variable to be initialized, and the view holder Viewholder as an inner class, although it is not possible to assign a value directly to the control object, but from the code logic you can see that the control is fetched from the layout file before the various setup methods are called. This means that the above control objects must first obtain instances, when they are used must be non-empty, so you can tell the compiler, these control objects must be assigned before use, the compiler you are old mercy, open one eye closed one eye release OK.

Needless to say, the idea is reasonable, Kotlin just provides the backdoor, it is the keyword lateinit. Lateinit means deferred initialization, which is placed in front of either Var or Val, indicating that the modified variable belongs to the deferred initialization attribute, even if no initialization is still non-empty. As a result, these controls do not need to be assigned a null value at the time of declaration, and there is no need to add two exclamation points when using them. Modify the previous Kotlin adapter according to the new Lateinit, and the rewritten Kotlin code looks like this:

Class Planetlistadapter (Private Val context:context, private Val planetlist:mutablelist<planet>, Private Val back Ground:int): Baseadapter () {Override Fun GetCount (): Int. = Planetlist.size override Fun GetItem (position:int): A NY = planetlist[position] Override fun Getitemid (position:int): Long = Position.tolong () override Fun GetView (posit        Ion:int, Convertview:view, Parent:viewgroup): view {var view = Convertview Val Holder:viewholder            if (Convertview = = null) {view = Layoutinflater.from (context). Inflate (R.layout.item_list_view, NULL) Holder = Viewholder ()//Declare the instance of the view holder first, and then get the internal control object Holder.ll_item = View.findviewbyid (r.id.ll_it EM) as LinearLayout Holder.iv_icon = View.findviewbyid (R.id.iv_icon) as ImageView holder.tv_name = V            Iew.findviewbyid (r.id.tv_name) as TextView Holder.tv_desc = View.findviewbyid (R.id.tv_desc) as TextView    View.tag = Holder    } else {holder = View.tag as Viewholder} val planet = planetlist[position] Holder.ll _item.setbackgroundcolor (background) holder.iv_icon.setImageResource (planet.image) Holder.tv_name.text = PLA    Net.name Holder.tv_desc.text = Planet.desc return view!! The properties in//viewholder use the keyword lateinit delay initialization inner class Viewholder {lateinit var ll_item:linearlayout latei NIT var iv_icon:imageview lateinit var tv_name:textview lateinit var Tv_desc:textview}}

The above Kotlin code is a bit of a look, although the overall code is not simple enough, but at least clear, the main use of Kotlin the following three technologies:

1. The constructor and initialization parameters are placed in the first row of the class definition, without having to be constructed separately or manually initialized;
2, such as GetCount, GetItem, getitemid three functions, simply return the numeric value of the simple operation, you can directly replace the curly brace with an equal sign;
3. For the internal control of the view holder, add lateinit before the variable name to indicate that the property is a deferred initialization property;


Grid view

In the previous List View section, given the Kotlin rewrite of the adapter class, through the keyword Lateinit is to avoid the trouble of empty check, but the control object will be initialized sooner or later, the late assignment is not as early as the assignment value. Turn to the implementation code of the previous planetlistadapter, carefully observe the discovery of the control object is actually dependent on the layout File View object views, in this case, you might want to use the View object as the Viewholder construction parameters passed, Allows the view holder to initialize an internal control at the time of construction. The Kotlin adapter code that is rewritten accordingly is as follows:

Class Planetgridadapter (Private Val context:context, private Val planetlist:mutablelist<planet>, Private Val back Ground:int): Baseadapter () {Override Fun GetCount (): Int. = Planetlist.size override Fun GetItem (position:int): A NY = planetlist[position] Override fun Getitemid (position:int): Long = Position.tolong () override Fun GetView (posit        Ion:int, Convertview:view, Parent:viewgroup): view {var view = Convertview Val Holder:viewholder if (view = = null) {view = Layoutinflater.from (context). Inflate (R.layout.item_grid_view, NULL) HOL            Der = Viewholder (view)//The Internal control object of the view holder is already initialized at the time of construction, so there is no need to assign a value View.tag = holder} else { Holder = View.tag as Viewholder} val planet = planetlist[position] Holder.ll_item.setBackground Color (background) holder.iv_icon.setImageResource (planet.image) Holder.tv_name.text = Planet.name Hol Der.tv_desc.text = Planet. DESC return view!! The properties in//viewholder are initialized at construction time inner class Viewholder (Val view:view) {val ll_item:linearlayout = View.findviewb Yid (R.id.ll_item) as linearlayout val Iv_icon:imageview = View.findviewbyid (R.id.iv_icon) as ImageView Val Tv_name:textview = View.findviewbyid (r.id.tv_name) as TextView val Tv_desc:textview = View.findviewbyid (R.id.tv_d ESC) as TextView}}

Using the adapter to run the test application, the resulting grid effect is shown, and the result is exactly the same as the Java code.

At this point, the Baseadapter-based Kotlin list adapter is over, the adapter code template above, and applies to the List view ListView with the grid view GridView.

Kotlin Primer (22) Simple optimization of the adapter

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.