В этом уроке:

- используем методы SetViewText и SetViewImage

 

Мы уже знаем, что SimpleAdapter умеет вставлять текст в TextView элементы и изображения в ImageView. Он использует для этого методы SetViewText и SetViewImage. Мы можем создать свой адаптер на основе SimpleAdapter и реализовать эти методы под наши цели.

Эти методы предоставляют нам View и данные, а значит мы можем менять View в зависимости от данных. В качестве примера, сделаем список, отражающий динамику некоего показателя в разрезе дней. Если динамика положительная – будем разукрашивать элементы в зеленый цвет, если отрицательная – в красный.

 

Создадим проект:

Project name: P0491_SimpleAdapterCustom1
Build Target: Android 2.3.3
Application name: SimpleAdapterCustom1
Package name: ru.startandroid.develop.p0491simpleadaptercustom1
Create Activity: MainActivity

 

Рисуем экран main.xml:

<?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>

На экране только список.

 

И 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="wrap_content"
    android:orientation="horizontal">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/ivImg"
            android:layout_width="30dp"
            android:layout_height="22dp"
            android:scaleType="fitCenter">
        </ImageView>
        <TextView
            android:id="@+id/tvValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:text="TextView"
            android:textSize="20sp">
        </TextView>
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/tvText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|center_horizontal"
                android:text="TextView"
                android:textSize="20sp">
            </TextView>
        </FrameLayout>
    </LinearLayout>
</LinearLayout>

Компонент ivImg будет отображать стрелку вниз или вверх, tvValue – значение динамики, tvText – номер дня.

 

Код MainActivity.java:

package ru.startandroid.develop.p0491simpleadaptercustom1;

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

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class MainActivity extends Activity {

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

  // картинки для отображения динамики 
  final int positive = android.R.drawable.arrow_up_float;
  final int negative = android.R.drawable.arrow_down_float;
  
  ListView lvSimple;

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

    // массив данных
    int[] values = { 8, 4, -3, 2, -5, 0, 3, -6, 1, -1 };

    // упаковываем данные в понятную для адаптера структуру
    ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
        values.length);
    Map<String, Object> m;
    int img = 0;
    for (int i = 0; i < values.length; i++) {
      m = new HashMap<String, Object>();
      m.put(ATTRIBUTE_NAME_TEXT, "Day " + (i + 1));
      m.put(ATTRIBUTE_NAME_VALUE, values[i]);
      if (values[i] == 0) img = 0; else
        img = (values[i] > 0) ? positive : negative;
      m.put(ATTRIBUTE_NAME_IMAGE, img);
      data.add(m);
    }

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

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

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

  class MySimpleAdapter extends SimpleAdapter {

    public MySimpleAdapter(Context context,
        List<? extends Map<String, ?>> data, int resource,
        String[] from, int[] to) {
      super(context, data, resource, from, to);
    }

    @Override
    public void setViewText(TextView v, String text) {
      // метод супер-класса, который вставляет текст
      super.setViewText(v, text);
      // если нужный нам TextView, то разрисовываем 
      if (v.getId() == R.id.tvValue) {
        int i = Integer.parseInt(text);
        if (i < 0) v.setTextColor(Color.RED); else
          if (i > 0) v.setTextColor(Color.GREEN);
      }
    }

    @Override
    public void setViewImage(ImageView v, int value) {
      // метод супер-класса
      super.setViewImage(v, value);
      // разрисовываем ImageView
      if (value == negative) v.setBackgroundColor(Color.RED); else
        if (value == positive) v.setBackgroundColor(Color.GREEN);
    }
  }
}

Код создания адаптера обычен. Придумываем данные values и упаковываем их в коллекцию Map-объектов. Каждый Map будет состоять из трех атрибутов

ATTRIBUTE_NAME_TEXT - текст с номером дня
ATTRIBUTE_NAME_VALUE - значение динамики
ATTRIBUTE_NAME_IMAGE - id картинки для отображения, в зависимости от значения (положительное или отрицательное)

Затем заполняем массивы сопоставления данных (from) и View (to), создаем адаптер, используя свой класс MySimpleAdapter, и настраиваем список.

 

Смотрим реализацию MySimpleAdapter. Конструктор вызывает конструктор супер-класса, тут ничего не меняем. Менять будем методы:

setViewText

Сначала выполняем метод супер-класса, который вставляет данные. А далее смотрим, если View, это тот TextView, который будет отображать значения, то меняем цвет текста на красный или зеленый в зависимости от значения, которое он будет отображать.

 

setViewImage

Выполняем метод супер-класса, чтобы ImageView получил изображение, а дальше меняем его фон в зависимости от значения. Картинка, которую мы вставляем , с альфа-слоем, поэтому фон будет виден. Проверку по id ImageView не выполняем, т.к. ImageView у нас только один.

 

Все сохраним и запускаем.

Отобразились картинка, значение и день. Фон картинки и цвет текста значения меняются в зависимости от значения – положительное или отрицательное.

 

Пример, конечно, не особо интересный, но надо было рассмотреть работу этих методов. Ничего лучше в голову не пришло )

 

На следующем уроке:

- используем свой SimpleAdapter.ViewBinder


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование



Похожие статьи


Последние статьи



Language

Система Orphus

Социальные сети

 

Telegram канал



Android чат в Telegram



Группа ВКонтакте



Страница в Facebook

Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal

Яндекс.Метрика