Этот вопрос задают много раз, но я не могу правильно понять, здесь я использую базу данных Sqlite для простых целей чата, и все ее сырье заполняется с помощью recyclerview. Что я должен был сделать?
- создать класс MyDbHandler расширяет SQLiteOpenHelper
- создать метод, который возвращает List
В классе Activity создайте экземпляр класса адаптера и передайте Список в адаптере.
publi c Класс MyDbHandler расширяет SQLiteOpenHelper {
public List<SqlMessages> sqlMessagesList()
{
String query = "SELECT * FROM " + TABLE_NAME;
List<SqlMessages> messagesList=new LinkedList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
SqlMessages sqlMessages;
if (cursor.moveToFirst()) {
do {
sqlMessages.setId(cursor.getLong(cursor.getColumnIndex(COLUMN_ID)));
sqlMessages.setFromid(cursor.getString(cursor.getColumnIndex(COLUMN_FROM)));
sqlMessages.setType(cursor.getString(cursor.getColumnIndex(COLUMN_TYPE)));
sqlMessages.setMessage(cursor.getString(cursor.getColumnIndex(COLUMN_MESSAGE)));
sqlMessages.setTimestamp(cursor.getLong(cursor.getColumnIndex(COLUMN_TIMESTAMP)));
messagesList.add(sqlMessages);
} while (cursor.moveToNext());
}
return messagesList;
}
}
Класс активности
messagesAdapter=new MessagesAdapter(myDbHandler.sqlMessagesList());
при добавлении нового сообщения
final SQLiteDatabase db= myDbHandler.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_MESSAGE, messageText);
values.put(COLUMN_FROM, MessageSenderId);
values.put(COLUMN_TYPE, TYPE_TEXT);
values.put(COLUMN_TIMESTAMP,tsLong);
long rowInserted = db.insert(TABLE_NAME,null, values);
if(rowInserted != -1)
{
Log.v("sqlitesave","ok");
messagesAdapter.notifyItemInserted(myDbHandler.sqlMessagesList().size()-1);
// to use of notifyItemInserted the app is crash(not every time but sometime) Logcat show below error
}
else
{
Log.v("sqlitesave","notok");
}
db.close();
LogCat
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{6cea9b9 position=15 id=-1, oldPos=14, pLpos:14 scrap [attachedScrap] tmpDetached no parent} android.support.v7.widget.RecyclerView{4aedc2 VFED..C.. ......I. 0,108-720,723 #7f080217 app:id/message_list_user}, adapter:".......".chat.MessagesAdapter@1cd2f63, layout:android.support.v7.widget.LinearLayoutManager@25f8760, context:"........".chat.MessageActivity@cd7aab8
at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5715)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5898)
Я пробовал messagesAdapter.notifyDataSetChanged (); он отлично работает, и этот тип вопросов, на который все разработчики отвечают, использует notifyDataSetChanged
, но для дальнейшей работы мне нужно использовать notifyItemInserted
Так как же правильно использовать notifyItemInserted для обработки этого исключения?