Как обновить listview android studio

Android: как обновить содержимое ListView?

Мой ListView использует расширение BaseAdapter , я не могу заставить его обновиться должным образом. Когда я обновляюсь, кажется, что старые данные рисуются поверх новых, пока не произойдет событие прокрутки. Старые строки рисуются поверх новых, но старые строки исчезают, когда я начинаю прокручивать.

Я пробовал позвонить invalidateViews() , notifyDataSetChanged() и notifyDataSetInvalidated() . Мой код выглядит примерно так:

9 ответов

Тем, у кого все еще есть проблемы, я решил это так:

Сначала я очистил данные от адаптера, затем добавил новую коллекцию элементов и только потом установил notifyDataSetChanged(); Сначала мне это было непонятно, поэтому я хотел указать на это. Обратите внимание, что без вызова notifyDataSetChanged() представление не будет обновлено.

Насколько я понимаю, если вы хотите обновить ListView сразу после изменения данных, вам следует вызвать notifyDataSetChanged() в RunOnUiThread() .

Вам не нужно создавать новый адаптер для обновления содержимого ListView. Просто сохраните свой адаптер в поле и обновите свой список следующим кодом:

Чтобы прояснить это, ваша Activity должна выглядеть так:

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

Если вы замените адаптер или включите адаптер снова и снова при обновлении списка, то ошибка принудительного закрытия наверняка вызовет проблемы в какой-то момент. (Ошибка: данные списка обновлены, но адаптер не уведомляет представление списка)

Я тоже пробовал invalidate (), invalidateViews (), notifyDataSetChanged (). Все они могли работать в определенных контекстах, но в моем случае это не помогло.

В моем случае мне пришлось добавить несколько новых строк в список, и это просто не работает. Создание нового адаптера решило проблему.

Во время отладки я понял, что данные есть, но не отображаются. Если invalidate () или invalidateViews () не отображает (что должно), я не знаю, что будет.

Создание нового объекта адаптера для обновления измененных данных не кажется плохой идеей. Это определенно работает. Единственным недостатком может быть время, затрачиваемое на выделение новой памяти для вашего адаптера, но это должно быть нормально, если система Android достаточно умна и позаботится об этом, чтобы поддерживать ее эффективность.

Если исключить это из уравнения, процесс будет почти таким же, как при вызове notifyDataSetChanged. В том смысле, что в любом случае вызывается один и тот же набор функций адаптера.

Таким образом, мы не теряем много, но многое приобретаем.

Я делаю то же самое, используя invalidateViews (), и у меня это работает. Если вы хотите, чтобы он немедленно стал недействительным, вы можете попробовать вызвать postInvalidate после вызова invalidateViews.

Обновите содержимое ListView с помощью кода ниже:

onCreate () :

onDataGet (после вызова веб-службы, из локальной базы данных или другого источника):

BaseAdapter :

Когда вы захотите обновить просмотр списка , просто вызовите код из двух строк ниже:

Готово

Только это работает для меня каждый раз, обратите внимание, что я не знаю, вызывает ли это какие-либо другие осложнения или проблемы с производительностью:

Источник

Лучший способ обновить адаптер / ListView на Android

Моя книга «Hello Android» дает это как способ использования пользовательского помощника db, настройки курсора, а затем настройки адаптера следующим образом:

С этим, однако, каждый раз, когда мне нужно обновить набор данных, мне нужно продолжать работать с этим блоком кода (который немного затрудняет внутри onClick () для кнопки из-за того, что «это» недоступно.

Это лучший способ обновить набор данных, или я должен посмотреть на удаление .close и выдачу адаптера.notifyDataSetChanged ()? Если я это сделаю, иногда я получаю силу как (и я не могу вспомнить на данный момент), но иногда она не может правильно удалить. Я думаю, это может быть из-за того, что база данных в настоящее время открыта, и она пытается открыть ее снова.

Читайте также:  Dead cells андроид не устанавливается

Должны ли мы также объявлять переменные для курсоров, DatabaseHelpers и Adapter в классе (вне OnCreate), чтобы они были доступны для всех функций?

Я понимаю, что это просто плохое программирование на данном этапе, но я пытаюсь понять, как лучше всего это делать.

Вы должны использовать adapter.notifyDataSetChanged() . Что говорит журнал, когда вы используете это?

Просто добавьте этот код перед установкой Adapter он работает для меня:

Или напрямую вы можете использовать метод ниже после изменения ресурса данных.

Следующий код отлично подходит для меня

Лучший способ обновить адаптер / ListView на Android

Не только вызов notifyDataSetChanged () обновит данные ListView, перед тем, как правильно загрузить информацию, необходимо вызвать setAdapter() :

Если вы используете LoaderManager, попробуйте с этим утверждением:

Возможно, их проблема – это момент, когда поиск выполняется в базе данных. В его циклах переопределения фрагментов его Fragment.java нужно просто выяснить: попробуйте провести тестирование с помощью методов:

Попробуйте аналогично поставить Log.i … «onStart» и «onResume».

Наконец, отредактируйте код в «onCreate» и поместите его в «onStart», например:

Просто напишите в своем Custom ArrayAdaper этот код:

Просто напишите в своем Custom ArrayAdaper этот код:

Источник

Android ListView обновить

У меня есть Listview который тянет и отображает данные из базы данных sqlite. Данные в первом столбце БД отображаются в ListView и при нажатии, Activity начинает показывать остальную часть столбца, связанного с первым столбцом. Когда данные редактируются, ListView необходимо обновить, чтобы отразить это, но он не показывает обновления, если приложение не перезапущено.

Я попытался вызвать, notifyDataSetChanged() и startActivityForResult() в моем onResume() но это не сработало. Какой метод следует использовать для выполнения обновления ListView в моем текущем коде?

Я понимаю, что SimpleCursorAdapter можно использовать, и я попытался реализовать этот код без успеха. Я новичок и нуждаюсь в реальном коде, чтобы понять, что нужно сделать.

Это то, для чего отлично подходит Loader . Я предлагаю вам создать SimpleCursorAdapter для привязки БД к пользовательскому интерфейсу ( ListView в этом случае), ContentProvider для взаимодействия с БД и CursorLoader для мониторинга БД для изменений и обновления интерфейса при необходимости. Loader будет обрабатывать все изменения базы данных и обновлять ListView , просто обновляя ваш адаптер. Похоже, что много работы впереди, но невероятно мощно настроено и будет работать через весь жизненный цикл Android.

Эти учебные пособия должны быть полезными:

редактировать

Вы теряете ссылку на свой список, почему ваш список не обновляется …

Сделайте это изменение в своем коде. 1. Инициализируйте свой ArrayList, когда он объявлен (глобально).

Непосредственно задайте список назначений для адаптера (onCreate)

LoginListAdapter = новый ArrayAdapter (это, android.R.layout.simple_list_item_1, loginArrayList);

onCreate() в onCreate() .

  • В вашем populateList() вместо добавления данных в новый список добавьте существующий список, связанный с вашим адаптером, т.е. loginArrayList
  • Если ваш список является полностью новым вызовом adapter.clear() и loginArrayList.clear() в loginArrayList.clear() populateList() перед добавлением данных в loginArrayList . После добавления данных в loginArrayList call adapter.notifyDataSetChanged()

    Это должно работать …

    1. Не выполняйте цикл, чтобы загрузить список. Если это простой список со всеми строками. Попробуйте использовать SimpleCursorAdapter и сделает ваше приложение более быстрым и коротким.
    2. После того, как вы обновите базу данных, то, что вы делаете, это запрос БД для получения Cursor и использования Adapter . swapCursor(newCursor) . Это обновит ваш список, сохранив положение прокрутки.

    Если вы вручную создаете резервные данные адаптера (в этом случае вы используете ArrayAdapter, что вполне приемлемо во многих случаях), то при изменении базы данных вам необходимо запрашивать базу данных, воссоздать свой набор данных, изменить Резервный набор данных вашего адаптера, и сообщите списку, который изменил набор данных.

    Способ достижения этого может заключаться в трансляции намерений, которые позволяют вашей деятельности знать, чтобы выполнить описанные выше шаги (поймав это намерение с помощью BroadcastReceiver).

    Вот мой пример кода для редактирования каждой строки, а также базы данных списка. Надеюсь, это поможет вам

    Сначала создайте имя адаптера «ListAdapterItem.java»

    И вот мой data_list_item

    И основной класс «Main.java»

    Укажите свой идентификатор каждого списка в списке, надеясь, что этот ответ на ваш вопрос

    Я думаю, что в вашем методе populate () перед блоком while вы должны вызвать loginListAdapter.notifyDataSetChanged () и loginListAdapter.clear (); Это позволит очистить адаптер и обратить внимание на новый список данных.

    Блок будет выглядеть так:

    Читайте также:  Android sdk make apk

    Я только что отредактировал, потому что порядок, который вы называете уведомлением и ясным, неверен. Ясное должно произойти после уведомления, это то, что я получил от своего опыта, если адаптер не перерисовал список.

    Попробуйте этот код

    В публичной области добавить переменную: List arrayList = new ArrayList ();

    И в onCreate () добавьте это:

    // затем добавим переменную в адаптер, как это

    Источник

    Как обновить Android listview?

    Как обновить Android ListView после добавления/удаления динамических данных?

    25 ответов

    вызов notifyDataSetChanged() на Adapter объект после изменения данных в этом адаптере.

    некоторые дополнительные сведения о том, как/когда звонить notifyDataSetChanged() можно посмотреть в это Google I / O видео.

    также вы можете использовать это:

    Пожалуйста, игнорируйте все invalidate() , invalidateViews() , requestLayout() , . ответы на этот вопрос.

    правильная вещь, чтобы сделать (и, к счастью, также отмечен как правильный ответ) является называть notifyDataSetChanged() на вашем адаптере.

    устранение неисправностей

    если вызов notifyDataSetChanged() не работает все методы компоновки не помогло. Поверьте мне ListView был должным образом обновлен. Если вам не удается найти разницу, вам нужно проверить, где данные в вашем адаптере от.

    если это просто коллекция, которую вы храните в памяти, проверьте, что вы фактически удалили или добавили элемент(ы) в коллекцию перед вызовом notifyDataSetChanged() .

    если вы работаете с базой данных или бэкэндом службы, вам придется вызвать метод для получения информации снова (или манипулировать данными в памяти) перед вызовом notifyDataSetChanged() .

    что это notifyDataSetChanged работает только если набор данных был изменен. Так что это место для посмотрите, если вы не найдете изменений. Отладка при необходимости.

    ArrayAdapter vs BaseAdapter

    я нашел, что работа с адаптером, который позволяет управлять коллекцией, как BaseAdapter работает лучше. Некоторые адаптеры, такие как ArrayAdapter, уже управляют собственной коллекцией, что затрудняет доступ к правильной коллекции для обновлений. Это действительно просто ненужный дополнительный уровень сложности в большинстве случаев.

    UI Thread

    это верно, что это должно быть вызвано из потока UI. Другие ответы содержат примеры того, как этого достичь. Однако это требуется только в том случае, если вы работаете над этой информацией вне потока пользовательского интерфейса. Это из службы или не потока пользовательского интерфейса. В простых случаях вы будете обновлять свои данные с помощью нажатия кнопки или другого действия / фрагмента. Так что все еще в потоке UI. Не нужно всегда вставлять этот runOnUiTrhead.

    Быстрый Пример Проекта

    можно найти в https://github.com/hanscappelle/so-2250770.git. Просто клонируйте и откройте проект в Android Studio (gradle). Этот проект имеет MainAcitivity здание ListView со всеми случайными данными. Этот список можно обновить с помощью меню действий.

    реализация адаптера, которую я создал для этого примера ModelObject предоставляет сбор данных

    Источник

    Google Android — это несложно

    Добро пожаловать на форум сайта

    Обновление ListView

    Обновление ListView

    Сообщение alexmx » 10 мар 2014, 08:25

    Re: Обновление ListView

    Сообщение Foenix » 10 мар 2014, 09:51

    Re: Обновление ListView

    Сообщение alexmx » 10 мар 2014, 10:00

    Re: Обновление ListView

    Сообщение Foenix » 10 мар 2014, 18:30

    Re: Обновление ListView

    Сообщение alexmx » 15 мар 2014, 21:09

    Так едем дальше. При помощи бубна и умного форумчанина Foenix был сколочен контент провайдер:
    Код
    [syntax=java]package ru.htsprovider.htspcontentprovider;

    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.net.Uri;
    import android.text.TextUtils;

    public class HTSProvider extends ContentProvider <

    static final String DB_NAME = «my.db»;
    static final int DB_VERSION = 1;

    //Таблица Каталога
    static final String CATALOG_TABLE = «catalogtable»;
    //Поля
    static final String CATALOG_ID = «_id»;
    static final String CATALOG_NAME = «catalogname»;
    //Скрипт создания таблицы
    static final String DB_CREATE = «create table » + CATALOG_TABLE + «(»
    + CATALOG_ID + » integer primary key autoincrement, »
    + CATALOG_NAME + » string»
    + «);»;

    //Таблица данных
    static final String DATA_TABLE = «datatable»;
    //Поля
    static final String DATA_ID = «_id»;
    static final String DATA_NAME = «dataname»;
    static final String DATA_TIME = «datatime»;
    //Скрипт создания таблицы
    static final String DBC_CREATE = «create table » + DATA_TABLE + «(»
    + DATA_ID + » integer primary key autoincrement, »
    + DATA_NAME + » string,»
    + DATA_TIME + » integer»
    + «);»;

    //URI
    //authority
    static final String AUTHORITY = «ru.htsprovider.htspdata»;
    //Path
    static final String CATALOG_PATH =»catalogtable»;
    static final String DATA_PATH = «datatable»;

    //Общий Uri
    //Каталог
    static final Uri CATALOG_CONTENT_URI = Uri.parse(«content://»
    + AUTHORITY + «/» + CATALOG_PATH);
    //Данные
    static final Uri DATA_CONTENT_URI = Uri.parse(«content://»
    + AUTHORITY + «/» + DATA_PATH);

    //Типы данных
    ////Набор строк
    //Каталог
    static final String CATALOG_CONTENT_TYPE = «vnd.android.cursor.dir/vnd.»
    + AUTHORITY + «.» + CATALOG_PATH;
    //Данные
    static final String DATA_CONTENT_TYPE = «vnd.android.cursor.dir/vnd.»
    + AUTHORITY + «.» + DATA_PATH;
    //Одна строка
    //Каталог
    static final String CATALOG_CONTENT_ITEM_TYPE = «vnd.android.cursor.item/vnd.»
    + AUTHORITY + «.» + CATALOG_PATH;
    //Данные
    static final String DATA_CONTENT_ITEM_TYPE = «vnd.android.cursor.item/vnd.»
    + AUTHORITY + «.» + DATA_PATH;

    Читайте также:  Ап стор только для андроида

    //// UriMatcher
    // общий Uri КАТАЛОГ
    static final int URI_CATALOG = 1;
    // Uri с указанным ID КАТАЛОГ
    static final int URI_CATALOG_ID = 2;
    // общий Uri ДАННЫЕ
    static final int URI_DATA = 3;
    // Uri с указанным ID ДАННЫЕ
    static final int URI_DATA_ID = 4;

    // описание и создание UriMatcher
    private static final UriMatcher uriMatcher;
    static <
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(AUTHORITY, CATALOG_PATH, URI_CATALOG);
    uriMatcher.addURI(AUTHORITY, CATALOG_PATH + «/#», URI_CATALOG_ID);
    uriMatcher.addURI(AUTHORITY, DATA_PATH, URI_DATA);
    uriMatcher.addURI(AUTHORITY, DATA_PATH + «/#», URI_DATA_ID);
    >

    DBHelper dbHelper;
    SQLiteDatabase db;

    public boolean onCreate() <
    dbHelper = new DBHelper(getContext());
    return true;
    >

    // чтение
    public Cursor query(Uri uri, String[] projection, String selection,
    String[] selectionArgs, String sortOrder) <
    Cursor cursor;
    String id;
    // проверяем Uri
    switch (uriMatcher.match(uri)) <
    case URI_CATALOG:
    // если сортировка не указана, ставим свою — по имени
    if (TextUtils.isEmpty(sortOrder)) <
    sortOrder = CATALOG_NAME + » ASC»;
    >
    db = dbHelper.getWritableDatabase();
    cursor = db.query(CATALOG_TABLE, projection, selection,
    selectionArgs, null, null, sortOrder);
    break;
    case URI_CATALOG_ID:
    > // добавляем ID к условию выборки
    if (TextUtils.isEmpty(selection)) <
    selection = CATALOG_ID + » = » + id;
    > else <
    selection = selection + » AND » + CATALOG_ID + » = » + id;
    >
    db = dbHelper.getWritableDatabase();
    cursor = db.query(CATALOG_TABLE, projection, selection,
    selectionArgs, null, null, sortOrder);
    break;
    case URI_DATA:
    if (TextUtils.isEmpty(sortOrder)) <
    sortOrder = DATA_NAME + » ASC»;
    >
    db = dbHelper.getWritableDatabase();
    cursor = db.query(DATA_TABLE, projection, selection,
    selectionArgs, null, null, sortOrder);

    break;
    case URI_DATA_ID:
    > // добавляем ID к условию выборки
    if (TextUtils.isEmpty(selection)) <
    selection = DATA_ID + » = » + id;
    > else <
    selection = selection + » AND » + DATA_ID + » = » + id;
    >
    db = dbHelper.getWritableDatabase();
    cursor = db.query(DATA_TABLE, projection, selection,
    selectionArgs, null, null, sortOrder);
    break;
    default:
    throw new IllegalArgumentException(«Wrong URI: » + uri);
    >
    cursor.setNotificationUri(getContext().getContentResolver(),
    CATALOG_CONTENT_URI);

    cursor.setNotificationUri(getContext().getContentResolver(),
    DATA_CONTENT_URI);
    return cursor;
    >

    public Uri insert(Uri uri, ContentValues values) <
    Uri resultUri;
    long rowID;
    switch (uriMatcher.match(uri)) <
    case URI_CATALOG:
    db = dbHelper.getWritableDatabase();
    rowID = db.insert(CATALOG_TABLE, null, values);
    resultUri = ContentUris.withAppendedId(CATALOG_CONTENT_URI, rowID);
    break;

    case URI_DATA:
    db = dbHelper.getWritableDatabase();
    rowID = db.insert(DATA_TABLE, null, values);
    resultUri = ContentUris.withAppendedId(DATA_CONTENT_URI, rowID);
    break;

    default:
    throw new IllegalArgumentException(«Wrong URI: » + uri);
    >
    getContext().getContentResolver().notifyChange(resultUri, null);
    return resultUri;
    >

    public int delete(Uri uri, String selection, String[] selectionArgs) <
    int cnt;
    String id;

    switch (uriMatcher.match(uri)) <
    case URI_CATALOG:
    db = dbHelper.getWritableDatabase();
    cnt = db.delete(CATALOG_TABLE, selection, selectionArgs);
    break;

    case URI_CATALOG_ID:
    > if (TextUtils.isEmpty(selection)) <
    selection = CATALOG_ID + » = » + id;
    > else <
    selection = selection + » AND » + CATALOG_ID + » = » + id;
    >
    db = dbHelper.getWritableDatabase();
    cnt = db.delete(CATALOG_TABLE, selection, selectionArgs);
    break;

    case URI_DATA:
    db = dbHelper.getWritableDatabase();
    cnt = db.delete(DATA_TABLE, selection, selectionArgs);
    break;

    case URI_DATA_ID:
    > if (TextUtils.isEmpty(selection)) <
    selection = CATALOG_ID + » = » + id;
    > else <
    selection = selection + » AND » + CATALOG_ID + » = » + id;
    >
    db = dbHelper.getWritableDatabase();
    cnt = db.delete(DATA_TABLE, selection, selectionArgs);
    break;

    default:
    throw new IllegalArgumentException(«Wrong URI: » + uri);
    >
    getContext().getContentResolver().notifyChange(uri, null);
    return cnt;
    >

    public int update(Uri uri, ContentValues values, String selection,
    String[] selectionArgs) <
    int cnt = 0;
    String id;

    switch (uriMatcher.match(uri)) <
    case URI_CATALOG:
    db = dbHelper.getWritableDatabase();
    cnt = db.update(CATALOG_TABLE, values, selection, selectionArgs);
    break;

    case URI_CATALOG_ID:
    > if (TextUtils.isEmpty(selection)) <
    selection = CATALOG_ID + » = » + id;
    > else <
    selection = selection + » AND » + CATALOG_ID + » = » + id;
    >
    break;

    case URI_DATA:
    db = dbHelper.getWritableDatabase();
    cnt = db.update(DATA_TABLE, values, selection, selectionArgs);
    break;

    case URI_DATA_ID:
    > if (TextUtils.isEmpty(selection)) <
    selection = DATA_ID + » = » + id;
    > else <
    selection = selection + » AND » + DATA_ID + » = » + id;
    >
    break;

    default:
    throw new IllegalArgumentException(«Wrong URI: » + uri);
    >
    getContext().getContentResolver().notifyChange(uri, null);
    return cnt;
    >

    public String getType(Uri uri) <
    switch (uriMatcher.match(uri)) <
    case URI_CATALOG:
    return CATALOG_CONTENT_TYPE;
    case URI_CATALOG_ID:
    return CATALOG_CONTENT_ITEM_TYPE;
    case URI_DATA:
    return DATA_CONTENT_TYPE;
    case URI_DATA_ID:
    return DATA_CONTENT_ITEM_TYPE;
    >
    return null;
    >

    private class DBHelper extends SQLiteOpenHelper <
    public DBHelper(Context context) <
    super(context, DB_NAME, null, DB_VERSION);
    >
    public void onCreate(SQLiteDatabase db) <
    db.execSQL(DB_CREATE);
    db.execSQL(DBC_CREATE);
    >
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) <
    >
    >
    >[/syntax]

    Только вот теперь зараза в следующем
    Подключился к провайдеру при помощи урезанного кода из урока 101:
    [syntax=java]package com.nuriy.clientcontent;

    import android.app.Activity;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.widget.ListView;
    import android.widget.SimpleCursorAdapter;

    public class MainActivity extends Activity <

    final String LOG_TAG = «myLogs»;

    final Uri DOCUM_URI = Uri.parse(«content://ru.htsprovider.htspdata/catalogtable»);

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

    Cursor cursor = getContentResolver().query(DOCUM_URI, null, null,
    null, null);
    startManagingCursor(cursor);

    String from[] = < "catalogname">;
    int to[] = < R.id.tvText1>;
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
    R.layout.item, cursor, from, to);

    ListView lvContact = (ListView) findViewById(R.id.lvContact);
    lvContact.setAdapter(adapter);
    >
    >
    [/syntax]

    Вставка данных происходит но данные на экране не меняются.
    Или же все таки лучше использовать cursorloader?
    Что посоветуете))

    Источник

    Оцените статью