В этом уроке:

- используем SimpleAdapter для построения списка
- добавляем и удаляем записи в списке

 

Как выводить данные в список с помощью SimpleAdapter мы знаем. Теперь попробуем эти данные менять. Сделаем список с возможностью удаления и добавления записей. Добавлять будем кнопкой, а удалять с помощью контекстного меню.

 

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

Project name: P0511_SimpleAdapterData
Build Target: Android 2.3.3
Application name: SimpleAdapterData
Package name: ru.startandroid.develop.p0511simpleadapterdata
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">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onButtonClick"
        android:text="Добавить запись">
    </Button>
    <ListView
        android:id="@+id/lvSimple"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

Кнопка для добавления и список. Из интересного можно отметить свойство onClick у кнопки. Дальше станет понятно, что это.

 

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">
    <ImageView
        android:id="@+id/ivImg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher">
    </ImageView>
    <TextView
        android:id="@+id/tvText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:text=""
        android:textSize="18sp">
    </TextView>
</LinearLayout>

Картинка и текст.

 

Код MainActivity.java:

package ru.startandroid.develop.p0511simpleadapterdata;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

  private static final int CM_DELETE_ID = 1;

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

  ListView lvSimple;
  SimpleAdapter sAdapter;
  ArrayList<Map<String, Object>> data;
  Map<String, Object> m;

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

    // упаковываем данные в понятную для адаптера структуру
    data = new ArrayList<Map<String, Object>>();
    for (int i = 1; i < 5; i++) {
      m = new HashMap<String, Object>();
      m.put(ATTRIBUTE_NAME_TEXT, "sometext " + i);
      m.put(ATTRIBUTE_NAME_IMAGE, R.drawable.ic_launcher);
      data.add(m);
    }

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

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

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

  public void onButtonClick(View v) {
    // создаем новый Map
    m = new HashMap<String, Object>();
    m.put(ATTRIBUTE_NAME_TEXT, "sometext " + (data.size() + 1));
    m.put(ATTRIBUTE_NAME_IMAGE, R.drawable.ic_launcher);
    // добавляем его в коллекцию
    data.add(m);
    // уведомляем, что данные изменились
    sAdapter.notifyDataSetChanged();
  }

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v,
      ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.add(0, CM_DELETE_ID, 0, "Удалить запись");
  }

  @Override
  public boolean onContextItemSelected(MenuItem item) {
    if (item.getItemId() == CM_DELETE_ID) {
      // получаем инфу о пункте списка
      AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) item.getMenuInfo();
      // удаляем Map из коллекции, используя позицию пункта в списке
      data.remove(acmi.position);
      // уведомляем, что данные изменились
      sAdapter.notifyDataSetChanged();
      return true;
    }
    return super.onContextItemSelected(item);
  }
}

В методе onCreate мы формируем коллекцию Map-объектов, массивы сопоставления, создаем адаптер и список, добавляем возможность контекстного меню для списка.

Метод onButtonClick – его мы указали в main.xml в свойстве onClick кнопки. И теперь при нажатии на кнопку выполнится этот метод. Отдельный обработчик нажатия не нужен.

В этом методе мы создаем новый Map, добавляем его к коллекции данных и сообщаем, что данные изменились и надо обновить список.

Метод onCreateContextMenu – создание контекстного меню. Создаем только один пункт - для удаления записи.

В onContextItemSelected обрабатываем нажатие на пункт контекстного меню. При вызове контекстного меню объект, для которого оно было вызвано, передает в меню информацию о себе. Чтобы получить данные по пункту списка, для  которого был совершен вызов контекстного меню, мы используем метод getMenuInfo. Объект AdapterContextMenuInfo содержит данные о View, id и позиции пункта списка. Мы используем позицию для удаления соответствующего Map из коллекции. После этого сообщаем, что данные изменились.

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

На скрине показано контекстное меню, которое вызывается при долгом нажатии на пункт списка. За ним виден список и кнопка для добавления записей.

Записи добавляются и удаляются. Редактирование я не стал делать. Там принцип тот же. Получаете Map и меняете его атрибуты.

 

Из кода видно, что для обновления списка надо поменять данные, которые использует адаптер, и вызвать его метод-уведомление.

 

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

- используем SimpleCursorAdapter для построения списка
- добавляем и удаляем записи в списке 

 


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

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

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

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

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

 

В канале я публикую ссылки на интересные и полезные статьи по Android

В чате можно обсудить вопросы и проблемы, возникающие при разработке



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



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

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal