A Dynamic Presentation

This technique — supplying an alternate layout to use for rows — handles simple cases very nicely. However, it isn’t sufficient when you have more-complicated scenarios for your rows, such as the following:

• 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 preceding 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 (from the FancyLists/Dynamic sample project at http://apress.com/):

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) {

   LayoutInflater inflater = context.getLayoutInflater();

   View row = inflater.inflate (R.layout.row, 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);

  }

 }

}

The theory is that we override getView() and return rows based on which object is being displayed, where the object is indicated by a position index into the Adapter. However, if you look at the implementation shown in the code here, you will see a reference to a LayoutInflater class — and that concept takes a little bit of an explanation.

A Bit About Inflation

In this case, “inflation” means the act of converting an XML layout specification into the actual tree of View objects the XML represents. This is undoubtedly a tedious bit of code: take an element, create an instance of the specified View class, walk the attributes, convert those into property setter calls, iterate over all child elements, lather, rinse, repeat.

The good news is that the fine folk on the Android team wrapped all that up into a class called LayoutInflater that we can use ourselves. When it comes to fancy lists, for example, we will want to inflate Views for each row shown in the list, so we can use the convenient shorthand of the XML layout to describe what the rows are supposed to look like.

In the preceding example, we inflate the R.layout.row layout we created in the previous section. This gives us a View object that, in reality, is our LinearLayout with an ImageView and a TextView, just as R.layout.row specifies. However, rather than having to create all those objects ourselves and wire them together, the XML and LayoutInflater handle the “heavy lifting” for us. 

And Now, Back to Our Story

So we have used LayoutInflater to get a View representing the row. This row is “empty” since the static layout file has no idea what actual data goes into the row. It is our job to customize

Вы читаете Beginning Android
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату