50. SimpleAdapter. We use ViewBinder

Lecture



In this lesson:

- we use our SimpleAdapter.ViewBinder

The SimpleAdapter adapter , in its operation, maps View components and values ​​from Map objects. How he does it by default and with which View components he can work with, we covered in previous lessons. But if we lack these capabilities, we can always create our own handler and assign it to the adapter.

To do this, use the setViewBinder method (SimpleAdapter.ViewBinder viewBinder), which requires a SimpleAdapter.ViewBinder object as input. We create our own version of this Binder and implement the setViewValue method (View view, Object data, String textRepresentation) in which we write all the logic of matching data and components (binding). The method returns a boolean value.

The algorithm of the adapter is as follows: it first checks whether the third-party binder was given to it.

If found, it executes its setViewValue method. If the method returns true , then the adapter assumes that the processing has been completed successfully, if false , then it performs the binding in its standard algorithm, which we discussed in previous lessons.

If the adapter does not find a third-party binder, it also performs standard binding.

Those. our task is to fill in the SimpleAdapter.ViewBinder.setViewValue method. And there are no restrictions on TextView or ImageView, any component can be processed and filled. Let's create an example in which we fill the ProgressBar value and change the color of the LinearLayout.

This will be a monitoring application that displays the level of capacity utilization of some system in the context of days. The ProgressBar will show the download level, and the entire list item will be tinted with color depending on the download level.

Create a project:

Project   name : P0501_SimpleAdapterCustom2
Build Target : Android 2.3.3
Application name : SimpleAdapterCustom2
Package name : ru.startandroid.develop.p0501simpleadaptercustom2
Create Activity : MainActivity

Draw the main.xml screen:

  <? xml version = "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: id = "@ + id / lvSimple"
android: layout_width = "match_parent"
android: layout_height = "wrap_content">
</ Listview>
</ LinearLayout>

Only a list.

We will need to create the res / values ​​/ colors.xml file , where we list the colors we need:

  <? xml version = "1.0" encoding = "utf-8"?> 
<resources>
<color name = "Bckgr"> # 9C9C9C </ color>
<color name = "Red"> # 33FF0000 </ color>
<color name = "Orange"> # 33FFFF00 </ color>
<color name = "Green"> # 3300FF00 </ color>
<color name = "Black"> # 000000 </ color>
</ resources>

Now create a layout for the list items res / layout / item.xml :

  <? 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"
android: background = "@ color / Bckgr">
<LinearLayout
android: id = "@ + id / llLoad"
android: layout_width = "match_parent"
android: layout_height = "wrap_content"
android: orientation = "vertical">
<Textview
android: id = "@ + id / tvLoad"
android: layout_width = "wrap_content"
android: layout_height = "wrap_content"
android: text = "TextView"
android: layout_gravity = "center_horizontal"
android: textColor = "@ color / Black">
</ TextView>
<ProgressBar
android: id = "@ + id / pbLoad"
style = "? android: attr / progressBarStyleHorizontal"
android: layout_width = "match_parent"
android: layout_height = "wrap_content"
android: layout_margin = "5dp"
android: max = "100">
</ ProgressBar>
</ LinearLayout>
</ LinearLayout>

llLoad - LinearLayout which occupies the entire list item, and which we will color,
tvLoad - text-info,
pbLoad is a loading indicator.

MainActivity.java code:

package ru.startandroid.develop.p0501simpleadaptercustom2;

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

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

// имена атрибутов для Map
final String ATTRIBUTE_NAME_TEXT = "text";
final String ATTRIBUTE_NAME_PB = "pb";
final String ATTRIBUTE_NAME_LL = "ll";

ListView lvSimple;

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

// массив данных
int load[] = { 41, 48, 22, 35, 30, 67, 51, 88 };

// упаковываем данные в понятную для адаптера структуру
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
load.length);
Map<String, Object> m;
for (int i = 0; i < load.length; i++) {
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_NAME_TEXT, "Day " + (i+1) + ". Load: " + load[i] + "%");
m.put(ATTRIBUTE_NAME_PB, load[i]);
m.put(ATTRIBUTE_NAME_LL, load[i]);
data.add(m);
}

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

// создаем адаптер
SimpleAdapter sAdapter = new SimpleAdapter(this, data, R.layout.item,
from, to);
// Указываем адаптеру свой биндер
sAdapter.setViewBinder(new MyViewBinder());

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

class MyViewBinder implements SimpleAdapter.ViewBinder {

int red = getResources().getColor(R.color.Red);
int orange = getResources().getColor(R.color.Orange);
int green = getResources().getColor(R.color.Green);

@Override
public boolean setViewValue(View view, Object data,
String textRepresentation) {
int i = 0;
switch (view.getId()) {
// LinearLayout
case R.id.llLoad:
i = ((Integer) data).intValue();
if (i < 40) view.setBackgroundColor(green); else
if (i < 70) view.setBackgroundColor(orange); else
view.setBackgroundColor(red);
return true;
// ProgressBar
case R.id.pbLoad:
i = ((Integer) data).intValue();
((ProgressBar)view).setProgress(i);
return true;
}
return false;
}
}
}

We look code. Fill the array of data download on a 100-point scale. We form the data for the adapter: in TextView we will transmit brief information ( String ), and in PgrogressBar and LinearLayout - the load value ( int ). We fill in the matching arrays, create an adapter, tell it to use our binder, and set up a list.

The MyViewBinder nested class is our Binder implementation. We need to implement the setViewValue method that the adapter will use to map data from the Map and View components. At the entrance to him go:

view - View component
data - data for it
textRepresentation - a textual representation of the data (data.toString () or an empty String, but never null)

So, we look implementation. First, we check which component we were given for processing.

In the case of llLoad, we expect data of type int, so we cast the Object to an Integer and get data on the load from the array. And then look at the level of this download. If less than 40, then we assume that everything is OK, the background color is green. From 40 to 70 - attention, the color is yellow. Above 70 - high load, red. Return true . It is important! Thus, we say to the adapter that we have successfully completed the binding for this component and we do not need to perform standard processing for it.

In the case of pbLoad, we also expect an int and perform the cast. And then just call the setProgress method and pass it the value. At the end, we return true - we have successfully processed the component ourselves, standard processing is not needed.

For all other View components, the setViewValue method will return false . This means the components will go to the standard processing adapter. In our case, tvLoad will go along this path and the adapter will transmit the text from the Map itself, our intervention is not necessary.

All save and run.

  50. SimpleAdapter.  We use ViewBinder

We get just such a picture. LinearLayout filled with color, ProgressBar displayed the loading level, TextView showed information about the bottom and loading.

In the next lesson:

- use SimpleAdapter to build a list
- add and delete entries in the list


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Mobile Programming (Android IOs)

Terms: Mobile Programming (Android IOs)