7

Per qualche motivo, quando si aggiunge un nuovo elemento a RecyclerView (deve essere inserito in cima all'elenco), non verrà visualizzato a meno che non si scorrerà verso il basso l'elenco e si esegua il backup su in alto, e anche senza animazione. (Appare in cima alla lista come se fosse lì tutto il tempo). La rimozione di un oggetto funziona correttamente con le animazioni corrette.RecyclerView - Nessuna animazione su 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:

Devo dire che se uso NotifyDataSetChanged invece di NotifyItemInserted, quindi il nuovo elemento viene visualizzato immediatamente, ma RecyclerView non scorrerà in cima all'elenco. (Manualmente per scorrere verso l'alto per vederlo).

risposta

16

Ciò accade perché LinearLayoutManager ritiene che l'articolo sia inserito sopra il primo elemento. Questo comportamento ha senso quando non si è in cima alla lista, ma capisco che non è intuitivo quando si è in cima alla lista. Possiamo cambiare questo comportamento, nel frattempo, è possibile chiamare linearLayoutManager.scrollToPosition(0) dopo aver inserito l'articolo se linearLayoutManager.findFirstCompletelyVisibleItemPosition() restituisce 0.

+0

Chiamo addRecording dall'interno di un servizio (dopo finisce MediaRecorder la cattura audio), quindi non sono sicuro del modo in cui mi chiamerei lm.scrollToPosition dal frammento:/ –

+0

realtà ho ho ottenuto quella parte qui sopra! il problema è, ho fatto setReverseLayout (true) e setStackFromEnd (true) durante la creazione di RecyclerView, quindi chiamare lm.scrollToPosition (0) mi porta in fondo alla vista .. un modo per risolvere questo problema? Forse questo è anche il motivo per cui notifyItemInserted (0) non si anima anche? Tuttavia, notifyItemRemoved (position) funziona in modo impeccabile .. e RecyclerView.ViewHolder mostra correttamente la parte superiore come posizione 0 quando si fa clic su un elemento. –

+0

modifica: ottenuto il funzionamento impostando la posizione su getItemCount() - 1, abbastanza stranamente .. ancora non animato però:/ (scusate per i commenti continui, stackoverflow che non mi consente di modificare) –

2

posso risolvere il problema utilizzando notifyItemChange prima voce. Proprio come questo:

((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(0, 0); 
adapter.notifyItemChanged(0); 
Problemi correlati