Android experts teach you how to create a omnipotent ListView GridView adapter, androidgridview

Source: Internet
Author: User

Android experts teach you how to create a omnipotent ListView GridView adapter, androidgridview

In our development project, listview is the most common control, which is also a difficult or prone to problems in android. It is hard to say that it is not simple to use, I believe that everyone will, for example, combine network access, asynchronously record images, slide cards, and nesting. Today I am writing an article about ListView, a universal adapter for GridView, and getCount In the adapter, getItem, getItemId, and getView are the four methods to be rewritten. The following describes the methods frequently written by the adapter class.

Layout File

<RelativeLayout xmlns: android = "http://schemas.android.com/apk/res/android"
Xmlns: tools = "http://schemas.android.com/tools"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent"
>
<ListView
Android: id = "@ + id/lv"
Android: layout_width = "fill_parent"
Android: layout_height = "fill_parent"
/>
</RelativeLayout>


Item Layout

<? Xml version = "1.0" encoding = "UTF-8"?>
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent"
Android: orientation = "vertical">
<TextView
Android: id = "@ + id/tvContent"
Android: layout_width = "fill_parent"
Android: layout_height = "40dp"
/>
</LinearLayout>

MainActivity, class

Public class MainActivity extends Activity {
Private ListView lv;
Private List <String> datas;
Private LayoutInflater inflater;
@ Override
Protected void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. activity_main );
Lv = (ListView) findViewById (R. id. lv );
Inflater = LayoutInflater. from (this );
Datas = new ArrayList <String> ();
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
Datas. add ("hello world ");
MyAdapter adapter = new MyAdapter ();
Lv. setAdapter (adapter );
}
Class MyAdapter extends BaseAdapter {
@ Override
Public int getCount (){
Return datas. size ();
}
@ Override
Public Object getItem (int position ){
Return datas. get (position );
}


@ Override
Public long getItemId (int position ){
Return position;
}


@ Override
Public View getView (int position, View convertView, ViewGroup parent ){
ViewHolder holder = null;
If (convertView = null ){
Holder = new ViewHolder ();
ConvertView = inflater. inflate (R. layout. item, null );
Holder. tvContent = (TextView) convertView. findViewById (R. id. tvContent );
ConvertView. setTag (holder );
} Else {
Holder = (ViewHolder) convertView. getTag ();
}
Holder. tvContent. setText (datas. get (position ));
Return convertView;
}
}

Static class ViewHolder {
TextView tvContent;
}
}

In the adapter, we find that the getView () method is actually different in every Implementation of the adapter. We need to optimize the encapsulation of the adapter. Now we want to encapsulate a universal adapter. How can we extract it? In fact, it is nothing more than the basic features of java object-oriented: abstraction, encapsulation, inheritance, and polymorphism. When we see that a piece of code appears in every class, then we 'd better encapsulate the same code into a parent class, and each class has different business methods, so we can implement it in its subclass, now we have thought of the abstract class in java. Now we can encapsulate the adapter method in a simple way:

MyBaseAdapter. java

Public abstract class MyBaseAdapter <T> extends BaseAdapter {
Private List <T> datas;
Private Context context;
Public MyBaseAdapter (List <T> datas, Context context ){
Super ();
This. datas = datas;
This. context = context;
}
@ Override
Public int getCount (){
Return datas. size ();
}
@ Override
Public Object getItem (int position ){
Return datas. get (position );
}
@ Override
Public long getItemId (int position ){
Return position;
}
@ Override
Public abstract View getView (int position, View convertView, ViewGroup parent );
}

We found that as long as we inherit this MyBaseAdapter, we can write less getCount, getItem, and getItemId. You only need to re-write the getView () method, which is further optimized than before. Now let's take a look at how to write the getView () method code.

@ Override
Public View getView (int position, View convertView, ViewGroup parent ){
ViewHolder holder = null;
If (convertView = null ){
Holder = new ViewHolder ();
ConvertView = inflater. inflate (R. layout. item, null );
Holder. tvContent = (TextView) convertView. findViewById (R. id. tvContent );
ConvertView. setTag (holder );
} Else {
Holder = (ViewHolder) convertView. getTag ();
}
Holder. tvContent. setText (datas. get (position ));
Return convertView;
}
}

Static class ViewHolder {
TextView tvContent;
}

Now we can see that the getView method is bound with the ViewHoler class. We know that ViewHolder uses converetView. setTag () is bound to it. In this way, when convertView is used again, you do not need findViewById. Because the view IDs are encapsulated in ViewHolder, we must write different ViewHolder classes. Now we want to create a common ViewHolder and continue to optimize the getView method,

That is to say, in fact, each convertView is bound to a ViewHolder object. This viewHolder is mainly used to help convertView store the layout controls, the ViewHolder class provides the setTag method, and the ViewHolder class provides an external method for obtaining the View object. Based on these two points, we write a ViewHolder class,

Public class ViewHolder {
Private View convertView;
Public void setTag (){
ConvertView. setTag (this );
}

Public View getView (){

Return convertView;
}
}

This ViewHolder cannot be used. The convertView variable is never used. First, it is set from the outside world through the set method, and second, it is passed through the constructor, however, if you initialize convertView through the constructor, you can create a ViewHolder object at will, so the constructor cannot be used externally. At this time, we will make the constructor private, therefore, we only need to provide a method to obtain ViewHoler, while ViewHolder is bound to convertView. If you know what to cache, check whether the cache is available. If not, go to new, make a judgment within the method. After talking about this, convert the idea into code to implement the following:

ViewHolder:

<Span style = "font-size: 18px;"> public class ViewHolder {private View mConvertView; private ViewHolder (Context context, ViewGroup parent, int layoutId, int position) {mConvertView = LayoutInflater. from (context ). inflate (layoutId, parent, false); mConvertView. setTag (this);}/*** get a ViewHolder object */public static ViewHolder get (Context context, View convertView, ViewGroup parent, int layoutId, int position) {if (convertView = null) {return new ViewHolder (context, parent, layoutId, position);} return (ViewHolder) convertView. getTag () ;}public View getConvertView () {return mConvertView ;}}</span>

The getView method of the adapter is as follows:

@ Overridepublic View getView (int position, View convertView, ViewGroup parent) {// instantiate a viewHolder ViewHolder viewHolder = ViewHolder. get (getApplicationContext (), convertView, parent, R. layout. item, position); return viewHolder. getConvertView ();}
At this time, my heart was shocked. I was very cool, and the interface was blank when I ran it. I went there. How can I set the view data to the interface, this is another time for the waste of cells. I thought about a layout with so many views. What should I do? God, I suddenly thought of the concept of a set. niubi doesn't, smoke, continue writing! Set? Can List be used? Why? Because the view on each item is searched by id, I immediately thought of using the Map set, but I don't need it. I use a built-in container of android, this class is called SparseArray.

Public class ViewHolder {private View mConvertView; private final SparseArray <View> mViews; private ViewHolder (Context context, ViewGroup parent, int layoutId, int position) {mViews = new SparseArray <View> (); mConvertView = LayoutInflater. from (context ). inflate (layoutId, parent, false); mConvertView. setTag (this);}/*** get a ViewHolder object */public static ViewHolder get (Context context, View convertView, ViewGroup parent, int layoutId, int position) {if (convertView = null) {return new ViewHolder (context, parent, layoutId, position);} return (ViewHolder) convertView. getTag ();} public View getConvertView () {return mConvertView;}/*** get the right control through the control Id, if not, add views */public <T extends View> T $ (int viewId) {View view = mViews. get (viewId); if (view = null) {view = mConvertView. findViewById (viewId); mViews. put (viewId, view) ;}return (T) view ;}}

The getView method in the Adapter is as follows:

Class MyAdapter extends MyBaseAdapter <String> {
Public MyAdapter (List <String> datas, Context context ){
Super (datas, context );
}
@ Override
Public View getView (int position, View convertView, ViewGroup parent ){
// Instantiate a viewHolder
ViewHolder viewHolder = ViewHolder. get (getApplicationContext (), convertView, parent,
R. layout. item, position );
TextView tvContent = viewHolder. $ (R. id. tvContent );
TvContent. setText (datas. get (position ));
Return viewHolder. getConvertView ();
}
}
}

Now there are several lines of code in an adapter. Is there much less code in the adapter before? Daniel writes very little code to implement the business. We are moving towards Daniel!


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.