Categories
tech

Adapters and ListView in Android

One of the graphic controls of the basic and probably the most used at the Android platform is no doubt the ListView. It is used to constitute lists, via an adapter this is applied inside it.

Theadapter we’re speaking about is an element that offers with the graphical illustration of the knowledge and the interplay with them, for each and every merchandise within the ListView. In this educational we can read about the more than a few adapters which can be already outlined within the surroundings Android, but in addition those who we will be able to put in force in keeping with our wishes, giving a glance additionally to the optimization of them. Finally, we can provide an explanation for learn how to take care of the listeners of the ListView.

Now let’s get started, first, in outline a ListView in our mission, inside a format that we can name major.xml:

<?xml model="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical" >
...
<ListView
android:identity="@+identity/listingViewDemo"
android:layout_width="fill_parent" android:layout_height="wrap_content" >
</ListView>
...
</LinearLayout>

The ListView shows the View received by means of an implementation of the interface ListAdapter this is handed during the approach:

Continues after the commercial…
public void setAdapter(ListAdapter adapter)

The interface ListAdapter implements the interface Adapter that, in combination, describe the show mode of all the listing of things. There are a number of implementations of this fashion, however what we can see on this article is theArrayAdapter.

ArrayAdapter

TheArrayAdapter is an implementation of the interface ListAdapter this is used to show an array of components the place each and every component of the listing is related to a Textual contentView. In the Textual contentView is displayed the toString() of the component.
TheArrayAdapter implements a number of other constructors to make use of in line with our wishes:

  • public ArrayAdapter(Context context, int idTextView, T [] items): This constructor expects along with the context and to the array, the identity of the Textual contentView, the place you’ll see each and every merchandise.
  • public ArrayAdapter(Context context, int useful resource, int idTextView, T [] object): In this situation, not like the opposite constructor it’s a must to specify – along with the identity of the Textual contentView, the format useful resource the place to search for the Textual contentView.
  • public ArrayAdapter(Context context, int useful resource, int idTextView, List<T> object): Same as above, with the adaptation that rather than the array we have now a listing of items.

There are others however those are those that we can use on this educational. The very first thing we wish to outline a format for the component the place it’s declared a Textual contentView. The document is the identify row.xml:

<?xml model="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" > <Textual contentView
android:identity="@+identity/textual contentViewList"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textual content="" android:padding="10dip"
android:textSize="22dip"/> </LinearLayout>

This is a format that is composed of each and every component of our listing from an array which in our case is an array of String. We will quickly see a whole instance:

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView; public magnificence DemoActivity extends Activity { @Override public void onCreate(Bundle storedInstanceState) {
tremendous.onCreate(storedInstanceState);
setContentView(R. format.major); ListView listingView = (ListView)to findViewByIdentification(R. identity.listingViewDemo); String [] array = {"Antonio","John","Michael","Joseph", "Leonardo", "Alessandro"}; ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R. format.row, R. identity.textual contentViewList, array);
listingView.setAdapter(arrayAdapter);
}
}

The instance above produces this consequence:

Esempio ListView ArrayAdapter

We analyze higher the code that implements the listing. In the next line of code, we have now been having a connection with the listing of the primary format. This reference is used to set the adapter:

ListView listingView = (ListView)to findViewByIdentification(R. identity.listingViewDemo);

In the next we have now created the array of String to show within the listing, after which we created the adapter:

String [] array = {"Antonio","John","Michael","Joseph", "Leonardo", "Alessandro"};
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(this, R. format.row, R. identity.textual contentViewList, array);

In the constructor of the adapter, we have now handed this that identifies the Context present. With R. format.row we have now specified the format the place to visit seek for the Textual contentView (R. identity.textual contentViewList) to show the toString() of the component, and in spite of everything we have now handed the array of strings to show.

There are inside the android platform sources are already utilized by default inside the adapter with no need to put in force any XML useful resource. These sources are applied already inside the magnificence android.R. We have two default layouts which can be android.R.format.simple_list_item_1 and android.R.format.simple_list_item_2. Let’s take a easy instance:

...
ArrayAdapter<String>(this, android.R.format.simple_list_item_1, array);
listingView.setAdapter(arrayAdapter);
...

Custom Adapter

Up to this time we have now created a listing which shows easy textual content components ranging from an array of String. Now, no longer all the time, we wish to constitute information so simple as the String, however I regularly wish to view the weather are structurally extra complicated. In the latter case it’s a must to put in force your personal parts.

TheArrayAdapter implements not directly the interface Adapter then incorporates the process getView(). To produce a customized part, we continue exactly within the redefinition of this system. First of all, let’s begin to put in force an object extra complicated to show within the listing. We wish to show a listing of contacts with first identify, ultimate identify and call quantity. We wish to show the identify and surname at the identical line, whilst the telephone quantity on the backside, with a inexperienced colour. Let us begin to outline a format in a position to showing the knowledge, as we proposed (the document name it rowcustom.xml):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical" > <Textual contentView
android:identity="@+identity/textual contentViewIdentify"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textual content="" /> <Textual contentView
android:identity="@+identity/textual contentViewQuantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textual content=""
android:textColor="#00AA00"
/> </LinearLayout>

We then applied a LinearLayout that encapsulates two Textual contentView on two rows, simply as we had deliberate. Now we transfer directly to the definition of a category Contact which implements the three fields of kind String, first identify, ultimate identify and call quantity:

public magnificence Contact { personal String identify; personal String surname; personal String telephone; public Contact(String identify, String surname, String telephone) { this.identify = identify; this.surname = surname; this.telephone = telephone;
} public String getname() { go back identify;
} public void setNome(String identify) { this.identify = identify;
} public String getCognome() { go back surname;
} public void setCognome(String surname) { this.surname = surname;
} public String getTelefono() { go back telephone;
} public void setTelefono(String telephone) { this.telephone = telephone;
} }

Now we wish to outline our customized adapter. Everything occurs during theoperation of inflating. Theinflating permits us to instantiate an object from a XML useful resource. Then, we override the process getView() of the category ArrayAdapter , and throughout the approach we compose the visualization with the component of our listing. Let’s see the code of all the adapter and when we check out to provide an explanation for the only steps:

import android.content material.Context;
import android.view.FormatInflater;
import android.view.View;
import android.view.ViewStaff;
import android.widget.ArrayAdapter;
import android.widget.Textual contentView; public magnificence CustomAdapter extends ArrayAdapter<Contact>{ public CustomAdapter(Context context, int textual contentViewResourceId, Contact [] items) { tremendous(context, textual contentViewResourceId, items);
} @Override public View getView(int place, View convertView, ViewStaff dad or mum) { FormatInflater inflater = (FormatInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R. format.rowcustom, null); Textual contentView identify = (Textual contentView)convertView.to findViewByIdentification(R. identity.textual contentViewIdentify); Textual contentView quantity = (Textual contentView)convertView.to findViewByIdentification(R. identity.textual contentViewQuantity); Contact c = getItem(place); identify.setText(c.getname()+" "+c.getCognome());
quantity.setText(c.getTelefono()); go back convertView;
}
}

Therefore, we have now received a connection with the FormatInflater device that permits us to assign the convertView , the format that we outlined within the XML. This has allowed us to have get admission to to the Textual contentView identify and call quantity. Through the process getItem(place) we take the Contact object and set the values within the respective Textual contentView. As you’ll see, the method is discreet, however no longer environment friendly, as it is rather heavy when it comes to sources, particularly after we are coping with lists with numerous pieces. It takes a technique of optimization that’s what we will see within the subsequent paragraph. Meanwhile, I depart you the Activity that implements the customized adapter we have now noticed above:

import java.util.RelatedList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView; public magnificence DemoActivity extends Activity {
@Override public void onCreate(Bundle storedInstanceState) {
tremendous.onCreate(storedInstanceState);
setContentView(R. format.major); ListView listingView = (ListView)to findViewByIdentification(R. identity.listingViewDemo); List<Contact> listing = new RelatedList<Contact>(); listing.upload(new Contact("Antonio","Coschignano","1234567890")); listing.upload(new Contact("John","Smith","1234567890")); listing.upload(new Contact("Joseph","White","1234567890")); listing.upload(new Contact("Leonardo","Da Vinci","1234567890")); listing.upload(new Contact("Mario","Rossi","1234567890")); listing.upload(new Contact("Aldo","Smith","1234567890")); CustomAdapter adapter = new CustomAdapter(this, R. format.rowcustom, listing);
listingView.setAdapter(adapter);
}
}

This is the outcome:

Esempio ListView ArrayAdapter

Optimization of the adapter

In the instance that we have got noticed over theinflating and the process to findByView() are performed for each and every component of the listing. These two operations are heavy when it comes to sources, so we wish to undertake tactics that permit us to scale back get admission to to those strategies. We can put in force a mechanism that permits us to accomplish those operations handiest as soon as, on a show of the listing, making the adapter a lot more environment friendly. Let’s see the code of theadapter (CustomAdapterOptimize):

import java.util.List;
import android.content material.Context;
import android.view.FormatInflater;
import android.view.View;
import android.view.ViewStaff;
import android.widget.ArrayAdapter;
import android.widget.Textual contentView; public magnificence CustomAdapterOptimize extends ArrayAdapter<Contact> { public CustomAdapterOptimize(Context context, int textual contentViewResourceId, List<Contact> items) { tremendous(context, textual contentViewResourceId, items);
} @Override public View getView(int place, View convertView, ViewStaff dad or mum) { go back getViewOptimize(place, convertView, dad or mum);
} public View getViewOptimize(int place, View convertView, ViewStaff dad or mum) { ViewHolder viewHolder = null; if (convertView == null) { FormatInflater inflater = (FormatInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R. format.rowcustom, null); viewHolder = new ViewHolder(); viewHolder.identify = (Textual contentView)convertView.to findViewByIdentification(R. identity.textual contentViewIdentify); viewHolder.quantity = (Textual contentView)convertView.to findViewByIdentification(R. identity.textual contentViewQuantity);
convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag();
} Contact touch = getItem(place); viewHolder.identify.setText(touch.getname()+" "+touch.getname());
viewHolder.quantity.setText(touch.getTelefono()); go back convertView;
} personal magnificence ViewHolder { public Textual contentView identify; public Textual contentView quantity;
}
}

The View magnificence permits us – by the use of the process setTag() – bind an object on your magnificence example. In our case we have now created the category ViewHolder which we can use to stay the references to the textview of the identify and call quantity. By doing so, we will be able to care for references handiest to the primary invocation of the process getView(), this avoids having to copy the operation for each and every component of the listing.

In the loading of the listing, this adapter might happen two states of loading. The first when the convertView is the same as null, then we’re on the first component of the listing. In this situation, we carry out the inflating and assign the weather to the viewHolder by means of developing an example and settandolo within the View by the use of the setTag(). By doing so the viewHolder is made to be had within the subsequent uploads. In the second one case, when the convertView isn’t null, we continue handiest in acquiring the connection with the ViewHolder:

...
} else { viewHolder = (ViewHolder) convertView.getTag();
}
...

ListView and listeners

For listeners , we imply the potential of taking pictures the occasions which can be generated after we click on or choose any merchandise within the listing. This permits us to go along with the development, an motion, which we put in force inside a selected interface. We see probably the most interfaces that we will be able to put in force:

OnItemClickListener

This listener handles the motion this is generated after we click on an merchandise within the listing:

OnItemClickListener click onListener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View View, int place, lengthy identity) {
...
}
};
listingView.setOnItemClickListener(click onListener);

OnItemLongClickListener

This is invoked after we click on ‘lengthy’ on a component:

OnItemLongClickListener longClickListener = new OnItemLongClickListener() { @Override public void onItemLongClick(AdapterView<?> adapter, View View, int place, lengthy identity) {
...
}
};
listingView.setOnItemLongClickListener(longClickListener);

As you’ll see, all strategies of the interfaces to obtain, as arguments, the adapter, the view, the site and identity. Through those subjects, we will be able to get admission to the component that we clicked. Take the case of the OnItemClickListener. If we want get admission to to the touch (which we have now applied above) this is related to the component that we clicked, simply continue on this means:

@Override
public void onItemClick(AdapterView<?> adapter, View View, int place, lengthy identity) { Contact c = (Contact)adapter.getItem(place);
}

The subject of the ListView may be very complicated, what we have now noticed on this information no doubt does no longer faux to have exhausted the subject. There are different forms of adapter, and different forms of lists are structurally extra complicated as ExpandlibleListView or the GridView that profit from different forms of adapter. Of route we can duvet those subjects in long term articles.