Android ArrayAdapter not clearing?



我在Android的ArrayAdapter的自定义实现中遇到了一个奇怪的问题。为了提供一些背景,我正在尝试更新ListView的内容,同时保留当前滚动位置。

我有一个服务,它执行一个线程来更新ListView中显示的数据。该数据存储在ArrayList中,该ArrayList用于为ListView生成一些自定义ArrayAdapter。当ListView中的项被按下(添加或删除项)时,适配器也会被更新。我过去只是在每次发生任何类型的更改时创建新的适配器,然后将这个新适配器设置为ListView。这起到了作用,但每次都会导致ListView滚动到顶部。考虑到我申请的性质,这是不可取的。ListView中的当前滚动位置必须在两次更新之间保持不变。

我没有创建新的适配器,而是开始使用适配器的clear()方法清除需要更新的适配器,然后使用适配器的add()方法重建适配器的项。这两个方法都是在适配器上调用的。适配器在其构造函数中都设置为notifyDataOnChange,因此我不必每次手动调用notiftyDatasetChanged()(尽管考虑到我的问题,我也尝试过手动调用它,但没有成功)。

以下是我的自定义适配器:

public class RealmAdapter extends ArrayAdapter<Realm>
{
    Context c;
    public RealmAdapter(Context context, int resource, int textViewResourceId)
    {               
        super(context, resource, textViewResourceId);
        setNotifyOnChange(true);
        c = context;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    { 
        ...
    }
...
}

长话短说,这是我的问题。当我在适配器上调用clear()时,适配器没有被清除。

下面是我的onPostExecute中的一个片段,它位于我的线程中,用于更新。我肯定会把它放在这里,这样它就会在UI线程上更新。我在UI活动中的一个私有方法中也复制了这个确切的代码。这个代码在任何一个地方都不起作用:

appState.favoriteAdapter.clear();
Log.d(LOG_TAG, "COUNT: " + appState.favoriteAdapter.getCount());
for(Realm r : appState.favorites) {
    appState.favoriteAdapter.add(r);
}
Log.d(LOG_TAG, "COUNT: " + appState.favoriteAdapter.getCount());

例如,如果上面的适配器中有3个项,那么在clear()之后调用getCount()将返回3而不是0。同样,如果appState.favorites ArrayList中只有2个项,则循环后的getCount()仍返回3,而不是2。因为适配器没有响应任何这些调用,所以无法以任何方式进行更新。如果有帮助的话,我可以稍后发布一个Logcat,但没有例外,也没有显示任何有用的内容。

经过几个小时的思考,我似乎遇到了一个问题,即适配器没有对任何更改它的方法的调用做出响应。我曾尝试将一个空的ArrayList传递到适配器的super()调用中,但这没有帮助。我是遗漏了什么,还是错误地使用了ArrayAdapter?我已经搜索了所有的地方,我已经检查了很多常见的问题,比如修改底层数组并期望它更新,不调用(或在我的大小写设置中为适配器)notifyDatasetChanged(),以及在底层集合上使用不受支持的操作。

favoriteAdapter的声明非常简单,包含在我的应用程序类中

public RealmAdapter favoriteAdapter;

以下是上面的收藏夹适配器的初始化:

if(appState.favoriteAdapter == null) {
    appState.favoriteAdapter = new RealmAdapter(c, R.layout.list_item, R.layout.realm_entry, appState.favorites);
}
else {
    appState.favoriteAdapter.clear();
    Log.d(LOG_TAG, "COUNT: " + appState.favoriteAdapter.getCount());
    for(Realm r : appState.favorites) {
        appState.favoriteAdapter.add(r);
    }
    Log.d(LOG_TAG, "COUNT: " + appState.favoriteAdapter.getCount());
}

上面的代码在我的UI线程和下载刷新数据的线程中。

在上面的代码下面,放置了一个过滤器:

if(appState.favoriteAdapter != null && RealmSelector.realmFilter != null)                   appState.favoriteAdapter.getFilter().filter(RealmSelector.realmFilter.getText().toString());

过滤器会影响清除列表吗?逻辑会指示不要。。。

我将过滤器应用于自定义ArrayAdapter。显然,这会干扰适配器本身添加和删除项目吗?我把这个代码添加到我的方法中,它现在正在工作:

if(appState.favoriteAdapter != null && realmFilter != null) {
     appState.favoriteAdapter.getFilter().filter(realmFilter.getText().toString());
}

我希望有人能解释为什么这很重要。我认为过滤器是用来选择适配器中项目的子集。在我的测试中,我将用于过滤器的文本框留空,因此不应该应用实际的过滤器文本。同样,如果有人知道发生了什么,并能向我解释为什么这能解决问题,我很想知道。

最新更新