|
The classic Android ListView is a plain list of
text — solid but uninspiring. This is the first in a series of posts where we will
see how to create a ListView with a bit more pizazz. Today, in particular,
we will see two techniques for creating a ListView whose rows contain
icons, in addition to text.
If you want rows to have a different look than the stock rows, one way to accomplish
this is to supply your own layout XML to be used for each row, telling Android to
use your layout rather than one of the built-in ones. This gives you complete control
over what goes in the row and how it is laid out.
For example, suppose you want a ListView whose entries
are made up of an icon, followed by some text. You could construct a layout for
the row that looks like this:
- <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- >
- <ImageView
-
android:id="@+id/icon"
-
android:layout_width="22px"
-
android:paddingLeft="2px"
-
android:paddingRight="2px"
-
android:paddingTop="2px"
-
android:layout_height="wrap_content"
-
android:src="@drawable/ok"
- />
- <TextView
-
android:id="@+id/label"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:textSize="44sp"
- />
- </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/icon"
android:layout_width="22px"
android:paddingLeft="2px"
android:paddingRight="2px"
android:paddingTop="2px"
android:layout_height="wrap_content"
android:src="@drawable/ok"
/>
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="44sp"
/>
</LinearLayout>
This layout uses a LinearLayout to set up a row, with the icon on
the left and the text (in a nice big font) on the right.
By default, though, Android has no idea that you want to use
this layout with your ListView. To make the connection, you need to
supply your Adapter with the resource ID of your custom layout:
- public
class StaticDemo extends
ListActivity {
- TextView selection;
- String[] items={"lorem",
"ipsum", "dolor",
"sit", "amet",
-
"consectetuer", "adipiscing",
"elit", "morbi",
"vel",
-
"ligula", "vitae",
"arcu", "aliquet",
"mollis",
-
"etiam", "vel",
"erat", "placerat",
"ante",
-
"porttitor", "sodales",
"pellentesque", "augue",
-
"purus"};
-
- @Override
- public
void onCreate(Bundle icicle) {
-
super.onCreate(icicle);
- setContentView(R.layout.main);
- setListAdapter(new
ArrayAdapter(this,
-
R.layout.row, R.id.label,
-
items));
- selection=(TextView)findViewById(R.id.selection);
- }
-
- public
void onListItemClick(ListView parent, View
v,int position, long
id) {
- selection.setText(items[position]);
- }
- }
public class StaticDemo extends ListActivity {
TextView selection;
String[] items={"lorem", "ipsum", "dolor", "sit", "amet",
"consectetuer", "adipiscing", "elit", "morbi", "vel",
"ligula", "vitae", "arcu", "aliquet", "mollis",
"etiam", "vel", "erat", "placerat", "ante",
"porttitor", "sodales", "pellentesque", "augue",
"purus"};
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
setListAdapter(new ArrayAdapter(this,
R.layout.row, R.id.label,
items));
selection=(TextView)findViewById(R.id.selection);
}
public void onListItemClick(ListView parent, View v,int position, long id) {
selection.setText(items[position]);
}
}
This example, derived from one of the ones in my
book, displays a list of random words,
and puts the currently-selected word in a TextView.
The key in this example is that you have told ArrayAdapter
that you want to use your custom layout (R.layout.row) and that the
TextView where the word should go is known as R.id.label
within that custom layout.
The result is a ListView with icons down the left
side. In particular, all the icons are the same.
This technique — supplying an alternate layout to use for rows
— handles simple cases very nicely. However, it falls down when you have more complicated
scenarios for your rows, such as:
-
Not every row uses the same layout (e.g., some have one line
of text, others have two)
-
You need to configure the widgets in the rows (e.g., different
icons for different cases)
In those cases, the better option is to create your own subclass
of your desired Adapter, override getView(), and construct
your rows yourself. The getView() method is responsible for returning
a View, representing the row for the supplied position
in the adapter data.
For example, let’s rework the above code to use getView(),
so we can have different icons for different rows — in this case, one icon for short
words and one for long words:
- public
class DynamicDemo extends
ListActivity {
- TextView selection;
- String[] items={"lorem",
"ipsum", "dolor",
"sit", "amet",
-
"consectetuer", "adipiscing",
"elit", "morbi",
"vel",
-
"ligula", "vitae",
"arcu", "aliquet",
"mollis",
-
"etiam", "vel",
"erat", "placerat",
"ante",
-
"porttitor", "sodales",
"pellentesque", "augue",
-
"purus"};
-
- @Override
- public
void onCreate(Bundle icicle) {
-
super.onCreate(icicle);
- setContentView(R.layout.main);
- setListAdapter(new
IconicAdapter(this));
- selection=(TextView)findViewById(R.id.selection);
- }
-
- public
void onListItemClick(ListView parent, View
v, int position, long
id) {
- selection.setText(items[position]);
- }
-
- class IconicAdapter
extends ArrayAdapter {
- Activity context;
-
- IconicAdapter(Activity
context) {
-
super(context, R.layout.row, items);
-
-
this.context=context;
- }
-
-
public View getView(int
position, View convertView, ViewGroup parent) {
-
ViewInflate inflater=context.getViewInflate();
-
View row=inflater.inflate(R.layout.row, null,
null);
-
TextView label=(TextView)row.findViewById(R.id.label);
-
-
label.setText(items[position]);
-
-
if (items[position].length()>4)
{
-
ImageView icon=(ImageView)row.findViewById(R.id.icon);
-
-
icon.setImageResource(R.drawable.delete);
-
}
-
-
return(row);
- }
- }
- }
public class DynamicDemo extends ListActivity {
TextView selection;
String[] items={"lorem", "ipsum", "dolor", "sit", "amet",
"consectetuer", "adipiscing", "elit", "morbi", "vel",
"ligula", "vitae", "arcu", "aliquet", "mollis",
"etiam", "vel", "erat", "placerat", "ante",
"porttitor", "sodales", "pellentesque", "augue",
"purus"};
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
setListAdapter(new IconicAdapter(this));
selection=(TextView)findViewById(R.id.selection);
}
public void onListItemClick(ListView parent, View v, int position, long id) {
selection.setText(items[position]);
}
class IconicAdapter extends ArrayAdapter {
Activity context;
IconicAdapter(Activity context) {
super(context, R.layout.row, items);
this.context=context;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewInflate inflater=context.getViewInflate();
View row=inflater.inflate(R.layout.row, null, null);
TextView label=(TextView)row.findViewById(R.id.label);
label.setText(items[position]);
if (items[position].length()>4) {
ImageView icon=(ImageView)row.findViewById(R.id.icon);
icon.setImageResource(R.drawable.delete);
}
return(row);
}
}
}
In our getView() implementation, we first get our
hands on a ViewInflate object, as described in the
previous
Building ‘Droids post, so we can use it to “inflate” our row layout XML and
give us a View representing that row.
Then, we tailor that View to match our needs:
-
We fill in the text label into our label widget, using the
word at the supplied position
-
We see if the word is longer than four characters and, if
so, we find our ImageView icon widget and replace the stock resource
with a different one
Now, we have a ListView with different icons based
upon context of that specific entry in the list. Obviously, this was a fairly contrived
example, but you can see where this technique could be used to customize rows based
on any sort of criteria, such as other columns in a returned Cursor.
Next time, we’ll take a closer look at the convertView
parameter to our getView() method and see how we can make use of it
to more efficiently render our list.
Source: http://androidguys.com/2008/07/14/fancy-listviews-part-one/
 |
ugg boots for sale
Elaine Goldstein, chairwoman of the accessories design department at the Fashion Institute of Technology. Consumers want their purchases to make them feel good about themselves, whether the rationale behind the buy is "They're so uggs outlet comfortable I'll wear them everywhere" or "They're so well-made I'll keep them for years." We're not embracing ugly shoes exclusively, but even the super-rich are dialing back the flash factor. Conspicuous consumption is the new toxic bachelor.