【问题标题】:Android RecyclerView: how to add new item to top of list?Android RecyclerView:如何将新项目添加到列表顶部?
【发布时间】:2017-01-11 04:23:21
【问题描述】:

我有一个 SQLite database 将数据推送到 CardView 以获得 RecyclerView 列表。我希望新添加的CardViews 插入到列表顶部,但它们被添加到底部,也就是列表的末尾。

MainActivity 中的这段代码似乎没有受到尊重,应该将新的 CardView 放在列表顶部:

contactList.add(0, contact);

我在这里错过了什么?

MainActivity.java

@Override
protected void onStart() {
    super.onStart();
    loadData();
}

void loadData(){
    sqLiteDB = new SQLiteDB(this);

    List<Contact> contactList = new ArrayList<>();

    Cursor cursor = sqLiteDB.retrieve();
    Contact contact;

    // iterate over the db cursor by using a new cursor for the ArrayList.
    try {
        if (cursor.moveToFirst()) {
            while (!cursor.isAfterLast()) { // to avoid an infinite loop iteration.
                do {
                    contact = new Contact();
                    contact.setId(cursor.getInt(0));
                    contact.setTodo(cursor.getString(1));

                    **contactList.add(0, contact);** // add the new item to top of R. list.
                } while (cursor.moveToNext());
            }
        }
    } finally {
        if(cursor !=null && !cursor.isClosed()){
            cursor.close();
        }
    }

    contactListAdapter.clear();
    contactListAdapter.addAll(contactList); 

SQLiteDB.java

public Cursor retrieve(){
    SQLiteDatabase db = getReadableDatabase();

    String[] projection = {
            ContactField.COLUMN_ID,
            ContactField.COLUMN_TODO
    };

    Cursor cursor = db.query(
            ContactField.TABLE_NAME,projection,              
            null,                    
            null,                    
            null,                    
            null,                    
            null                     
    );

    if (cursor == null) {
        return null;
    }

    return cursor;
}

ContactListAdapter.java

public class ContactListAdapter extends RecyclerView.Adapter<ContactListAdapter.ContactHolder>{

private List<Contact> contactList;
private Context context;
private RecyclerItemClickListener recyclerItemClickListener;
// Setting to -1 keeps the first CardView (position 0) from having its
// BackGroundColor mistakenly switch from the default to the highlighted/selected
// color which is red.
private int selectedPos = -1;

public ContactListAdapter(Context context) {
    this.context = context;
    this.contactList = new ArrayList<>();
}

public void clear() {
    while (getItemCount() > 0) {
        remove(getItem(0));
    }
}

public void addAll(List<Contact> contactList) {
    for (Contact contact : contactList) {
        // add(contact);
        contactList.add(0, contact);        }
}

// Get the Item's position.
public Contact getItem(int position) {
    return contactList.get(position);
}

// Get the Item's Id.
public long getItemId(int position) {
    return contactList.get(position).getId();
}
...

【问题讨论】:

  • 您应该删除内部的 do/while 并离开 cursor.moveToNext()。还要检查在您的addAll 方法中,联系人的顺序是否正确。另外记得修改适配器列表后调用contactListAdapter.notifyDataSetChanged()
  • 好的,我会尝试删除内部的do/while。如何在 addAll 方法中检查联系人的顺序是否正确?
  • 您可以设置断点并进行调试,或者您可以打印每个联系人以查看它们是否按顺序加载。
  • 是的,好吧...工作时间过长...需要撤回并重新关注全局!
  • @AJW 如果您在应用程序的完整生命周期中调用一次addAll() 方法,我认为您的代码没有任何问题。是这样吗?还是在数据库发生更改时重复调用它?

标签: android android-recyclerview android-cursor


【解决方案1】:

在下面的 sn-p 中添加元素而不是开始(参考contactList.add(contact); 行的评论)

try {
        if (cursor.moveToFirst()) {
            while (!cursor.isAfterLast()) { // to avoid an infinite loop iteration.
                do {
                    contact = new Contact();
                    contact.setId(cursor.getInt(0));
                    contact.setTodo(cursor.getString(1));

                    contactList.add(contact); // just add the new item to list normally.
                } while (cursor.moveToNext());
            }
        }
    } finally {
        if(cursor !=null && !cursor.isClosed()){
            cursor.close();
        }
    }

只需按如下方式更改您的 addAll() 方法

public void addAll(List<Contact> contactList) {
    for (Contact contact : contactList) {
        //add(contact);
        yourList.add(0, contact);
    }
}

同样在clearAll方法中只写youList.clear()

【讨论】:

  • 啊,好的,我试试看。
  • 所以我理解正确,上面的“yourList”就是我的“contactList”?
  • 不幸的是,这不起作用。经过测试,添加的第一个 CardView 返回了一个空白的 RecyclerView 列表,因此 View 发生了一些事情。第二个 CardView 使应用程序崩溃。
  • 好的,我会在上面加载。
  • 我添加了额外的代码...剩余的代码在可能不受影响的 ViewHolder 和 onBindViewHolder 部分中。
猜你喜欢
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-26
相关资源
最近更新 更多