7

Z jakiegoś powodu, po dodaniu nowego przedmiotu do RecyclerView (powinien on zostać wstawiony na początek listy), nie pojawi się, dopóki nie przewińę listy i nie powrócę do do góry i bez żadnej animacji. (Po prostu pojawia się na górze listy tak, jakby był cały czas). Usunięcie elementu działa dobrze z odpowiednimi animacjami.RecyclerView - Brak animacji na 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 Database:

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; 
} 

Listener:

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

edit:

należy wspomnieć, że jeśli mogę użyć zamiast NotifyDataSetChanged z NotifyItemInserted, to nowy element pojawia się natychmiast, ale RecyclerView nie przewinie do góry listy. (Ręcznie trzeba przewinąć w górę, aby to zobaczyć).

Odpowiedz

16

To się dzieje, ponieważ LinearLayoutManager uważa, że ​​element został wstawiony powyżej pierwszego elementu. Takie zachowanie ma sens, gdy nie jesteś na górze listy, ale rozumiem, że jest niezrozumiałe, gdy jesteś na szczycie listy. Możemy zmienić to zachowanie, w międzyczasie możesz zadzwonić pod numer linearLayoutManager.scrollToPosition(0) po wstawieniu elementu, jeśli linearLayoutManager.findFirstCompletelyVisibleItemPosition() zwróci 0.

+0

Dzwonię addRecording od wewnątrz a Service (po MediaRecorder kończy przechwytywanie audio), więc nie jestem pewien sposób nazwałbym lm.scrollToPosition z fragmentu:/I rzeczywiście –

+0

mam tę część powyżej! Problem polega na tym, że podczas tworzenia widoku RecyclerView wykonałem setReverseLayout (true) i setStackFromEnd (true), więc wywołanie lm.scrollToPosition (0) przenosi mnie do BOTTOM widoku .. w jaki sposób to naprawić? Być może dlatego również notyfikacja notifyItemInserted (0) nie jest animowana? Jednak notifyItemRemoved (pozycja) działa bezbłędnie .. a RecyclerView.ViewHolder poprawnie pokazuje górną pozycję 0 po kliknięciu elementu. –

+0

edytuj: dostałem go do pracy ustawiając pozycję getItemCount() - 1, co dziwne .. nadal nie jest animowany:/ (przepraszam za ciągłe komentarze, stackoverflow nie pozwala mi edytować) –

2

Naprawię to za pomocą pierwszego elementu notifyItemChange. Podobnie jak to:

((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(0, 0); 
adapter.notifyItemChanged(0); 
Powiązane problemy