7

По какой-то причине при добавлении нового элемента в RecyclerView (должен быть вставлен в начало списка) он не будет отображаться, если я не прокручу вниз список и не вернусь к сверху и без анимации. (Просто появляется в верхней части списка, как если бы он был там все время). Удаление элемента отлично работает с надлежащей анимацией.RecyclerView - нет анимации на NotifyItemInsert

RecyclerViewAdapter:

@Override 
public void onNewDatabaseEntryAdded() { 
    //item added to top of the list 
    notifyItemInserted(0); 
} 

public FileViewerAdapter(Context context) { 
    super(); 
    mContext = context; 
    mDatabase = new DBHelper(mContext); 
    mDatabase.setOnDatabaseChangedListener(this); 
} 

базы данных SQLite:

private static OnDatabaseChangedListener mOnDatabaseChangedListener; 

public static void setOnDatabaseChangedListener(OnDatabaseChangedListener listener) { 
    mOnDatabaseChangedListener = listener; 
} 

public long addRecording(String recordingName, String filePath, long length) { 

    SQLiteDatabase db = getWritableDatabase(); 
    ContentValues cv = new ContentValues(); 
    cv.put(DBHelperItem.COLUMN_NAME_RECORDING_NAME, recordingName); 
    cv.put(DBHelperItem.COLUMN_NAME_RECORDING_FILE_PATH, filePath); 
    cv.put(DBHelperItem.COLUMN_NAME_RECORDING_LENGTH, length); 
    cv.put(DBHelperItem.COLUMN_NAME_TIME_ADDED, System.currentTimeMillis()); 
    long rowId = db.insert(DBHelperItem.TABLE_NAME, null, cv); 

    if (mOnDatabaseChangedListener != null) { 
     mOnDatabaseChangedListener.onNewDatabaseEntryAdded(); 
    } 

    return rowId; 
} 

СЛУШАТЕЛЬ:

public interface OnDatabaseChangedListener{ 
    void onNewDatabaseEntryAdded(); 
    void onDatabaseEntryRenamed(); 
} 

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

Следует отметить, что, если я использую NotifyDataSetChanged вместо NotifyItemInserted, то новый элемент отображается немедленно, но RecyclerView не будет прокручиваться до верхней части списка. (Вручную нужно прокрутить вверх, чтобы увидеть его).

ответ

16

Это происходит потому, что LinearLayoutManager считает, что элемент вставлен над первым элементом. Такое поведение имеет смысл, когда вы не находитесь в верхней части списка, но я понимаю, что это неинтуитивно, когда вы находитесь в верхней части списка. Мы можем изменить это поведение, между тем, вы можете позвонить linearLayoutManager.scrollToPosition(0) после вставки элемента, если linearLayoutManager.findFirstCompletelyVisibleItemPosition() возвращает 0.

+0

Я звоню addRecording изнутри службы (после MediaRecorder завершения захвата звука), так что я не уверен, как я бы назвал lm.scrollToPosition из фрагмента:/ –

+0

на самом деле я получил эту часть выше! проблема в том, что я создал setReverseLayout (true) и setStackFromEnd (true) при создании RecyclerView, поэтому вызов lm.scrollToPosition (0) приводит меня к BOTTOM представления. любой способ исправить это? Возможно, это также почему notifyItemInserted (0) также не оживляет? Однако notifyItemRemoved (позиция) работает безупречно .. и RecyclerView.ViewHolder правильно показывает верхнюю позицию как позицию 0 при нажатии на элемент. –

+0

Редактирование: получил его на работу, установив позицию на getItemCount() - 1, как ни странно .. все еще не анимированный:/ (извините за непрерывные комментарии, stackoverflow не позволяет мне редактировать) –

2

Я исправлю его, используя notifyItemИзменить первый элемент. Так же, как это:

((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(0, 0); 
adapter.notifyItemChanged(0); 
Смежные вопросы