Lesson 48. Using SimpleAdapter.

Lesson 48. Using SimpleAdapter.


In this lesson:

– Consider an example of using SimpleAdapter

SimpleAdapter works with this type of List > – that is, a collection of Map objects (or heirs). If you look at the list, then everyone is Map contains data for the corresponding points list. To let the adapter know which ones data in which View-components of each item in the list to insert it, we specify two arrays: String[] from and int[] that. In from, we list the keys from Map, and in to the ID of View components. the adapter iterates View from the array that and compare them value with Map by keys from from.

Let’s look at this as an example. Let’s create a small list, each item of which will consist of a checkbox, a text box and a picture.

Let’s create a project:

Project name: P0481_SimpleAdapter
Build Target: Android 2.3.3
Application name: SimpleAdapter
Package name: ru.startandroid.develop.p0481simpleadapter
Create Activity: MainActivity

we draw a screen main.xml:



    
    

Only LIstView is here.

create item.xml for the list item:



    
    
    
        
        
        
        
    

ImageView, CheckBox, and TextView will each represent each item in the list.

we write code MainActivity.java:

package ru.startandroid.develop.p0481simpleadapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

  // имена атрибутов для Map
  final String ATTRIBUTE_NAME_TEXT = "text";
  final String ATTRIBUTE_NAME_CHECKED = "checked";
  final String ATTRIBUTE_NAME_IMAGE = "image";

  ListView lvSimple;

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // массивы данных
    String[] texts = { "sometext 1", "sometext 2", "sometext 3",
        "sometext 4", "sometext 5" };
    boolean[] checked = { true, false, false, true, false };
    int img = R.drawable.ic_launcher;

    // упаковываем данные в понятную для адаптера структуру
    ArrayList> data = new ArrayList>(
        texts.length);
    Map m;
    for (int i = 0; i < texts.length; i++) {
      m = new HashMap();
      m.put(ATTRIBUTE_NAME_TEXT, texts[i]);
      m.put(ATTRIBUTE_NAME_CHECKED, checked[i]);
      m.put(ATTRIBUTE_NAME_IMAGE, img);
      data.add(m);
    }

    // массив имен атрибутов, из которых будут читаться данные
    String[] from = { ATTRIBUTE_NAME_TEXT, ATTRIBUTE_NAME_CHECKED,
        ATTRIBUTE_NAME_IMAGE };
    // массив ID View-компонентов, в которые будут вставлять данные
    int[] to = { R.id.tvText, R.id.cbChecked, R.id.ivImg };

    // создаем адаптер
    SimpleAdapter sAdapter = new SimpleAdapter(this, data, R.layout.item,
        from, to);

    // определяем список и присваиваем ему адаптер
    lvSimple = (ListView) findViewById(R.id.lvSimple);
    lvSimple.setAdapter(sAdapter);
  }
}

Let’s parse the code. We create constants for attribute names, describe arrays of data, and pack this data in ArrayList > (Img we will have the same for everyone). Next, we define the two arrays that will be used to map the data and the View components. massif from contains Map key names, And an array that ID View-component. That is, a value from Map element with ATTRIBUTE_NAME_TEXT key, etc. will be inserted into R.id.tvText. in order. After that we create the adapter and associate it with the list.

We will save everything and run it. We see that everything is as we planned.

the adapter has gone over View-components (array that) For each item in the list and compared them with Map (massif from). That is, the mapping map is something like this:

R.id.tvText – Map.get (ATTRIBUTE_NAME_TEXT)
R.id.cbChecked – Map.get (ATTRIBUTE_NAME_CHECKED)
R.id.ivImg – Map.get (ATTRIBUTE_NAME_IMAGE)

And how does the adapter understand what methods and what View components should be called to pass values ​​to them from Map? He looks at type The View component, and depending on it, already determines how to work with it. For him there are three types:

1) View, inherit Checkable interface. Examples are CheckBox, CheckedTextView, CompoundButton, RadioButton, Switch, ToggleButton. In this case, the adapter checks if the corresponding value is of Map type boolean. If so, then the Checkable.setChecked method is called. Otherwise we will get an error.

Since version 2.2 the algorithm has changed a bit – added another branch of logic. Now if the value from Map is NOT boolean, Then it is verified that View is the heir TextView. If so, a text value from Map is inserted.

2) View what is TextView or his heirs. The SimpleAdapter.setViewText method is simply called here, and it already calls TextView.setText and passes values ​​there from Map.

3) View what is ImageView or his heirs. The adapter checks the data type from Map:

– if they can be brought (instanceof) to an Integer type, then the SimpleAdapter.setViewImage (ImageView v, int value) method is called, and it already calls ImageView.setImageResource.

otherwise the SimpleAdapter.setViewImage (ImageView v, String value) method is called, which again tries to bring the value to int and invokes the ImageView.setImageResource method, and if it does not, then converts the string to Uri (Uri.parse) and calls the ImageView.setImageURI (Uri) method.

If View does not fit into any of the three types listed above, we will get an error.

Let’s experiment a bit and try to insert the same text in CheckBox as in TextView. The adapter will be able to do this (if Android version is 2.2 and above) because CheckBox is the heir TextView.

To do this, rewrite the arrays:

    // массив имен атрибутов, из которых будут читаться данные
    String[] from = { ATTRIBUTE_NAME_TEXT, ATTRIBUTE_NAME_CHECKED,
        ATTRIBUTE_NAME_IMAGE, ATTRIBUTE_NAME_TEXT };

    // массив ID View-компонентов, в которые будут вставлять данные
    int[] to = { R.id.tvText, R.id.cbChecked, R.id.ivImg, R.id.cbChecked };

We have instructed the adapter to instruct R.id.cbChecked (CheckBox) to insert text from Map into the ATTRIBUTE_NAME_TEXT key.

Save, run.

Text successfully inserted into CheckBox.

Now let’s try to pass the data incorrectly. For example, instead of the image id, pass the boolean to R.id.ivImg. To do this, change from:

    // массив имен атрибутов, из которых будут читаться данные
    String[] from = { ATTRIBUTE_NAME_TEXT, ATTRIBUTE_NAME_CHECKED,
        ATTRIBUTE_NAME_CHECKED, ATTRIBUTE_NAME_TEXT };

Save, run.

We see that there is no picture. The adapter determined that it was not Integer transmitted and tried to display a Uri image from a textual boolean interpretation, but it did not work.

In general, the thing is not bad, but the functionality is quite limited – to put a pebble, to specify a picture and to place the text. Next time, try to extend the functionality to your needs.

I think it makes sense to say that if you put and remove a peg in points, then the adapter data does not change.

In the next lesson:

– we use the methods SetViewText and SetViewImage




Discuss in the forum [85 replies]

Leave a Comment