Listview更新列表后滚动到列表末尾


292

我想确保在使用listAdapter更新listview之后,列表一直滚动到底部,以便它显示列表中最后输入的元素。我怎样才能做到这一点 ?

我尝试了这个,但是没有运气:

lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

谢谢


尝试这样做是可行的... messageListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); messagesListView.setStackFromBottom(true);
Superdev 2014年

lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL)仅确保在调用adapter.notifyDataSetChanged之后将listView向下滚动。如果这不起作用,请尝试在xml中定义此属性,如下面的文章所示。
tomm,2015年

Answers:


418

假设您知道列表数据已更改,则可以通过将列表选择设置为最后一行来手动告诉列表滚动到底部。就像是:

private void scrollMyListViewToBottom() {
    myListView.post(new Runnable() {
        @Override
        public void run() {
            // Select the last row so it will scroll into view...
            myListView.setSelection(myListAdapter.getCount() - 1);
        }
    });
}

@Bhupendra不需要。您也可以不使用线程,如Warting的答案所示。
sagarpatidar 2014年

2
@Bhupendra setSelection()更新UI。通过在视图上调用post(Runnable),可以确保Runnable代码在android UI线程上运行。通常,除非您知道自己已经在UI线程上,或者通过其他方法确保已这样做,否则通常采用这种方式。
梅森·李

5
看来在新设置的适配器上使用post会导致滚动动画,同时确保其位于主线程中;设置适配器后立即使用setSelection不会导致滚动动画
Gianluca P.

1
@SaifHamed,正如Mason Lee在对Kevin的回答中所评论的那样,这也导致短列表在视图的顶部而不是底部(最可能不是预期的行为)具有“空”空间。
2015年

16
您还可以使用myListView.smoothScrollToPosition(myListAdapter.getCount()-1); 平滑滚动
Zar E Ahmer

238

您需要在列表视图中使用以下参数:

  • 滚动 lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

  • 将列表的头部设置在底部 lv.setStackFromBottom(true);

您还可以在XML中设置这些参数,例如。像这样:

<ListView
   ...
   android:transcriptMode="alwaysScroll"
   android:stackFromBottom="true" />

27
请注意,使用这种方法时,在添加行时,这些行“从底部堆叠”。这意味着短列表在视图的顶部而不是底部将具有“空”空间,这并不总是人们想要的。
Mason Lee)

2
快速提问:我可以通过什么方式使滚动动画化?当前导致当我notifyDataSetChanged()它没有动画跳?!?
Georg

@Georg您是否已在设备的“开发人员选项”中禁用了动画?
JonasCz-恢复莫妮卡

35

TRANSCRIPT_MODE_ALWAYS_SCROLL和setSelection的组合对我有用

ChatAdapter adapter = new ChatAdapter(this);

ListView lv = (ListView) findViewById(R.id.chatList);
lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
lv.setAdapter(adapter);

adapter.registerDataSetObserver(new DataSetObserver() {
    @Override
    public void onChanged() {
        super.onChanged();
        lv.setSelection(adapter.getCount() - 1);    
    }
});

29

我已经成功地使用它来响应按钮单击,所以我想您也可以在更新内容后使用它:

myListView.smoothScrollToPosition(theListAdapter.getCount() -1);

1
这是一个很好的解决方案。简单,一行。
乔什·拉尔森

12

要将其添加到ListFragment中:

getListView().setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); 
getListView().setStackFromBottom(true);`

添加了此答案,因为如果有人用Google搜索ListFragment的相同问题,他只会找到这个。

问候


9

使用:将列表的顶部设置在底部 lv.setStackFromBottom(true);

为我工作,列表首次显示时会自动滚动到底部。然后,列表将按滚动TRANSCRIPT_MODE_ALWAYS_SCROLL


6
请注意,使用这种方法时,在添加行时,这些行“从底部堆叠”。这意味着短列表在视图的顶部而不是底部将具有“空”空间。
李森(Mason Lee)

5

我用

setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);

在底部添加条目,而较旧的条目则从顶部向下滚动,例如聊天记录


呼叫getListView().smoothScrollToPosition(getListAdapter.getCount() - 1);处理通信,滚动到在活动开始时的底部。
palindrom

4

最简单的解决方案是:

    listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
    listView.setStackFromBottom(true);

3

记录本模式是您想要的,并由Google Talk和SMS / MMS应用程序使用。添加项目时,是否在适配器上正确调用了notifyDatasetChanged()?


我是。列表已正确更新,但始终从顶部开始。我只需要它来添加新项目,并始终滚动到列表的末尾。
jramirez

短信模式实际上是由SMS应用程序禁用的。我不记得为什么。
Timmmm 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.