Android 在列表视图中每次刷新时保持滚动位置

Android 在列表视图中每次刷新时保持滚动位置,android,listview,scroll,Android,Listview,Scroll,我在我的应用程序中设置了一个计时器,我可以从web服务中获取一些信息,并生成一个要显示的列表视图。现在我的问题是,每次计时器运行时,都要滚动回到开始 如何在列表视图中每次刷新时保持滚动位置 我的部分代码: runOnUiThread(new Runnable() { public void run() { /** * Updating parsed JSON data into ListView * */ ListAdap

我在我的应用程序中设置了一个计时器,我可以从web服务中获取一些信息,并生成一个要显示的列表视图。现在我的问题是,每次计时器运行时,都要滚动回到开始

如何在列表视图中每次刷新时保持滚动位置

我的部分代码:

runOnUiThread(new Runnable() {
    public void run() {
        /**
         * Updating parsed JSON data into ListView
        * */
        ListAdapter adapter = new SimpleAdapter(DashboardActivity.this, 
                                                all_chat, 
                                                R.layout.list_item, 
                                                new String[] { TAG_FULLNAME,
                                                               TAG_DATE, 
                                                               TAG_MESSAGE }, 
                                                new int[] { R.id.fullname,
                                                            R.id.date, 
                                                            R.id.message }
                                               );
        // updating listview
        setListAdapter(adapter);
    }
});

TNx.

您可以将以下属性添加到xml格式的
列表视图中

android:stackFromBottom="true"
android:transcriptMode="alwaysScroll" 
添加这些属性,您的
列表视图将始终绘制在底部,就像您希望它出现在聊天中一样

或者,如果您想将其保持在原来的位置,请将
alwaysScroll
替换为
normal

in the android:transcriptMode attribute. 

干杯

有一个。对于第一部分,只需使用
ListView#setSelectionFromTop(int)
ListView
保持在相同的可见位置。为了防止ListView闪烁,解决方案是简单地阻止ListView布局它的子对象。

不要调用
setAdapter()
。这样做:

ListAdapter adapter; // declare as class level variable

runOnUiThread(new Runnable() {
    public void run() {
        /**
         * Updating parsed JSON data into ListView
         */
        if (adapter == null) {
            adapter = new SimpleAdapter(
                    DashboardActivity.this, all_chat, R.layout.list_item, new String[]{TAG_FULLNAME, TAG_DATE, TAG_MESSAGE},
                    new int[]{R.id.fullname, R.id.date, R.id.message});
            setListAdapter(adapter);
        } else {
            //update only dataset   
            allChat = latestetParedJson;
            ((SimpleAdapter) adapter).notifyDataSetChanged();
        }
        // updating listview
    }
});
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());

// ...

// restore index and position
mList.setSelectionFromTop(index, top);

我也遇到了同样的问题,尝试了很多方法来阻止列表更改其滚动位置,包括:

android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
并且不调用
listView.setAdapter()
直到我发现:

看起来是这样的:

ListAdapter adapter; // declare as class level variable

runOnUiThread(new Runnable() {
    public void run() {
        /**
         * Updating parsed JSON data into ListView
         */
        if (adapter == null) {
            adapter = new SimpleAdapter(
                    DashboardActivity.this, all_chat, R.layout.list_item, new String[]{TAG_FULLNAME, TAG_DATE, TAG_MESSAGE},
                    new int[]{R.id.fullname, R.id.date, R.id.message});
            setListAdapter(adapter);
        } else {
            //update only dataset   
            allChat = latestetParedJson;
            ((SimpleAdapter) adapter).notifyDataSetChanged();
        }
        // updating listview
    }
});
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());

// ...

// restore index and position
mList.setSelectionFromTop(index, top);
说明:


ListView.getFirstVisiblePosition()
返回顶部可见的列表项。但此项可能会部分滚动到视图之外,如果要恢复列表的确切滚动位置,则需要获取此偏移量。因此
ListView.getChildAt(0)
返回顶部列表项的
视图
,然后
View.getTop()-mList.getPaddingTop()
返回其相对于
ListView
顶部的相对偏移量。然后,为了恢复
列表视图的滚动位置,我们调用
列表视图。setSelectionFromTop()
,其中包含我们想要的项目的索引和从
列表视图顶部定位其上边缘的偏移量,这些链接的可能重复不能解决我的问题,因为我的问题是另一回事。我的listview自动接收来自Web服务的数据,然后将位置滚动回开始位置(顶部位置)…,我希望您重新启动我。。。在人身上,他每次设置新的适配器时,他都应该更新它,或者使用addElement之类的函数,然后调用notifyDataSetChange。。在第二次检查您的问题之后,您应该这样做:调用clear、调用addelement in-loop、调用notifydatasetchange。清除取决于您的元素是否始终是新的,或者是否每次都与某些新闻设置适配器相同似乎很糟糕,但人们仍在继续这样做…是否
allChat
all\u chat
变量相同?将allChat传递给适配器构造函数,然后更改allChat引用并不意味着将在适配器中更改allChat。