Ошибка Android? Неправильная строка начинает анимацию в ListView после обновления БД во время анимации элемента правильного элемента

У меня есть ListView, который берет данные из БД. Каждая строка при нажатии анимируется вправо и назад следующим образом:

@Override
    public void onItemClick(AdapterView<?> av, View v, int pos, long id) {

...
          pos = pos - mList.getFirstVisiblePosition();
          mList.getChildAt(pos).startAnimation(anim );
...}

анимация длится около 1 секунды и выглядит следующим образом: выдвиньте вправо, затем скользните назад

Эта часть работает нормально, если во время анимации нет взаимодействия с БД

Теперь каждый элемент из списка имеет счетчик в БД. Всякий раз, когда пользователь нажимает на элемент из списка, счетчик должен увеличиваться в БД, и это также визуально отображается в ListView для каждого элемента.

Итак, БД видна через ContentProvider

Вот в чем проблема:

Всякий раз, когда я нажимаю на элемент, запускается анимация, а затем выполняется обновление в БД через ContentResolver. Проблема в том, что анимация начинается с нужного элемента, но сразу после ее запуска внезапно останавливается и завершается на другом элементе из списка.

Итак, если у меня есть четыре элемента в списке

----------1----------
----------2----------
----------3----------
----------4----------

и я нажимаю элемент 1, номер 1 начинает скользить вправо, но примерно через 200 мс он останавливается, а элемент 4 продолжает анимацию с того места, где остановился 1, до конца анимации.

То же самое можно воспроизвести, если я нажму 2, но на этот раз цифра 3 завершает анимацию. Если 3, то 2 заканчивается. Если я нажму 4, то 1.

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

Это всегда противоположный элемент. Я отлаживаю позицию в onItemClick, но она всегда правильная.

ВАЖНО Когда я комментирую код, выполняющий обновление в БД, все работает нормально. Это говорит о том, что проблема возникает, когда SimpleCursorAdapter ListView обновляется новым курсором через LoaderManager из БД во время анимации.

ЧТО я пробовал, используя CommonsWare Loaderex вместо ContentProvider. Тот же эффект дает.

ФРАГМЕНТЫ КОДА

public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
  return new CursorLoader(this.getActivity(), MyContentProvider.CONTENT_URI,
            new String[]{}, "uid>0 AND distance<80000", null, "distance LIMIT 100");
}


public void onLoadFinished(Loader<Cursor> ld, Cursor c) {
    merchantAdapter.swapCursor(c);
}

OnItemClick имеет этот код:

ContentResolver cr = getActivity().getContentResolver();
                ContentValues cv = new ContentValues();
                cv.put("counter", counter);
                Uri mUri = ContentUris.withAppendedId(MyContentProvider.CONTENT_URI, uid);
                cr.update(mUri, cv, null, null);

Что меня также беспокоит, так это то, что я не смог заставить LoaderManager автоматически обновлять список для меня, поэтому после вышеприведенного cr.update(...

Я делаю это, чтобы обновлять список после каждого обновления

getActivity()).lm.getLoader(0).forceLoad();

Может ли проблема с анимацией быть ошибкой Android? или что мне не хватает?

Текущая идея для решения этой проблемы Я предполагаю, что мой вариант состоит в том, чтобы заблокировать клики на время анимации и сделать cr.update в обработчике после того, как продолжительность анимации прошла, чтобы обновление не влияло на анимацию.

пожалуйста, порекомендуйте


person AndroidGecko    schedule 25.09.2012    source источник


Ответы (1)


Теперь я могу подтвердить, что: такое поведение происходит только на моем устройстве 2.2. И его можно воспроизвести. Он отлично работает (анимация завершается правильно, когда строки обновляются в bg) на устройстве Android 4.1, и его можно воспроизвести.

В настоящее время я решаю это, так как я хочу поддерживать устройства 2.2. Я создаю слушателя этой анимации. когда anim завершится, я обновлю базу данных. Также я блокирую пользовательский интерфейс на время анимации (около 300 мс, так что все в порядке)

ПРИМЕЧАНИЕ. Это похоже на проблему Android SDK.

Что касается проблемы обновления и использования forceLoad, в моей реализации поставщика контента мне пришлось добавить это в метод запроса:

cursor.setNotificationUri(getContext().getContentResolver(), uri);

который регистрирует этот uri в ContentResolver. теперь он отлично работает без использования forceLoad

person AndroidGecko    schedule 02.10.2012