[The break is the silent rhythm in the music, just like the silent voice at this time; while the note is the voice in the music, it is Sung, however, the value of a certain note is the same as that of a certain break]
--- Basic five-line spectrum tutorial
Abstract base class of a custom Adapter
Android project development usually uses listview, gridview, and other controls that need to be used with the adapter. When there are many interfaces and multiple listview with different lalistview s, naturally, multiple adapter classes need to be defined.
Generally, to improve flexibility, we will allow the custom adapter to inherit from the baseadapter and rewrite the four abstract functions. The typical class structure is as follows:
Public class mybaseadapter extends baseadapter {@ overridepublic int getcount () {return 0 ;}@ overridepublic object getitem (INT position) {return NULL ;}@ overridepublic long getitemid (INT position) {return 0 ;}@ overridepublic view getview (INT position, view convertview, viewgroup parent) {return NULL ;}}
However, only the above Code can not implement the required functions, because the adapter is designed to provide data for the view, so it needs to be further improved on the basis of the above Code, first of all, because the data type is changing, therefore, the generic representation type is used. Second, there are usually many data entries. Therefore, a container is required to store data. Here, the common arraylist is used. Finally, the adapter also needs to maintain a reference to the view, and may need to use the context of Android. In the jamendo project, the view class corresponds to listview, context uses the activity where listview is located. Therefore, the following general abstract classes that encapsulate baseadapter are obtained. The getview function is left to the subclass for implementation.
Public abstract class arraylistadapter <t> extends baseadapter {protected arraylist <t> MList; // The data container protected activity mcontext; // The Android context environment protected listview mlistview; // use listviewpublic arraylistadapter (activity context) {mcontext = context;} @ overridepublic int getcount () {If (MList! = NULL) {return MList. Size () ;}else {return 0 ;}@ overridepublic object getitem (INT position) {return MList = NULL? Null: MList. get (position) ;}@ overridepublic long getitemid (INT position) {return position ;}// Leave It To The subclass implementation, because different listview listitem la s are different @ overrideabstract public view getview (INT position, view convertview, viewgroup parent); // Changes the data in the adapter, you need to refresh listviewpublic void setlist (arraylist <t> List) {This. MList = List; policydatasetchanged ();} public void setlist (T [] list) {arraylist <t> arraylist = new arraylist <t> (list. length); For (T: List) {arraylist. add (t);} setlist (arraylist);} public arraylist <t> getlist () {return MList;} public listview getlistview () {return mlistview ;} public void setlistview (listview) {mlistview = listview ;}}
Adapter system and implementation in erjamendo
The sub-classes of arraylistadapter are used for listview. Each sub-class implements the abstract function getview of the parent class, implements the layout of list items in this function, and returns the view corresponding to the list items. This article will not elaborate on the view corresponding to each adapter. It will be involved in the subsequent analysis of each interface. Here, we only use downloadjobadapter as an example to illustrate the general implementation method of the subclass of arraylistadapter.
As shown in, the download management page is displayed. The first item in the list is the view after the download is complete, and the second item is the view being downloaded. It can be seen that the view returned by the downloadjobadapter's getview function contains at least: displays the textview of the song name, The textview of the album name, The textview indicating the download progress, and a progress bar.
The static internal class viewholder defined in the downloadjobadapter class shows that the list items on the download page are indeed composed of the above four controls:
Static class viewholder {textview songname; textview songartistalbum; textview songprogresstext; progressbar ;}
The getview function generally uses the viewholder mode to optimize the performance and avoid unnecessary repetitive work. Since Android caches convertview for us, first determine whether the input parameter convertview is null. If it is null, this view has never been created and needs to be created; otherwise, it indicates that this is the cache of the previously constructed view. Because the layout resources remain unchanged, the corresponding control resources can be reused. These control resources are stored using viewholder, which facilitates the use of the settag function of convertview to store it as a whole in convertview.
It can be noted that the settag function also has an overloaded function, which is defined as follows:
Public void settag (final object tag) {mtag = tag;} public void settag (INT key, final object tag) {// if the package ID is 0x00 or 0x01, it's either an undefined package // or a framework ID if (Key >>> 24) <2) {Throw new illegalargumentexception ("The key must be an application-specific" + "resource ID. ");} settaginternal (this, key, tag);} Private Static void settaginternal (view, int key, object tag) {sparsearray <Object> tags = NULL; synchronized (stagslock) {If (stags = NULL) {stags = new weakhashmap <view, sparsearray <Object> ();} else {tags = stags. get (View) ;}}if (tags = NULL) {tags = new sparsearray <Object> (2); synchronized (stagslock) {stags. put (view, tags) ;}} tags. put (Key, tag );}
As you can see, settag (object) stores the object in the mtag of the View class member variable, while settag (INT, object) then weakhashmap is used to establish the weak reference relationship between the view and the object to be stored. If you need to store multiple objects in the view, you can use the second overload function. Note that settag (INT, object) the Int type parameter must be defined in RES/values/strings. XML file in the following format:
<Resources> <item type = "ID" name = "Wen"/> <item type = "ID" name = "asce"/> </resources>
Reference in the Code as follows:
// Convertview when tag is set. settag (R. id. wen, "wen1885"); convertview. settag (R. id. asce, "asce1885 ");... // string Wen = convertview when obtaining the tag. gettag (R. id. wen); string asce = convertview. gettag (R. id. asce );
Finally, let's take a look at the key code of the getview function of the downloadjobadapter class:
Viewholder holder = NULL; If (convertview = NULL) {layoutinflater Inflater = mcontext. getlayoutinflater (); convertview = Inflater. inflate (R. layout. download_row, null); holder = new viewholder (); holder. songname = (textview) convertview. findviewbyid (R. id. trackrowname); holder. songartistalbum = (textview) convertview. findviewbyid (R. id. trackrowartistalbum); holder. songprogresstext = (textview) convertview. findviewbyid (R. id. trackrowprogress); holder. progressbar = (progressbar) convertview. findviewbyid (R. id. progressbar); // The control resources are stored in convertview as a whole. settag (holder); mcontext. registerforcontextmenu (convertview);} else {holder = (viewholder) convertview. gettag ();}