为什么android:transcriptMode="normal"无法正常工作?

6
我一直在处理一个问题。每当我的列表视图(适配器)添加一个项目时,如果我在最后一个项目处,我希望它自动滚动(到某种程度上确实会这样)。但是,如果同时添加3个或更多的项目,则不会自动滚动。

以下是该列表视图的XML:

    <ListView android:id="@android:id/list"
    android:layout_width="fill_parent" 
    android:layout_height="0dip"
    android:layout_weight="1"
    android:transcriptMode="normal"/>

我尝试使用一个我在这里找到的片段进行解决。

我的代码如下:

public void addChat(final String text, final String username) {
    this.runOnUiThread(new Runnable() {
        public void run() {
            globals.chatAdapter.add(DateFormat.format("hh:mmaa", Calendar.getInstance()).toString(), username, text);

            globals.chatAdapter.notifyDataSetChanged();

            int lastP = getListView().getLastVisiblePosition();
            int count = globals.chatAdapter.getCount() - 1;

            if (lastP == globals.chatAdapter.oldP || lastP == -1) {
                getListView().setSelection(count);
            }

            globals.chatAdapter.oldP = count;
        }
    });
}

这种情况下,如果一次出现大量项目,则getListView()。getLastVisiblePosition()不会立即更新,导致setSelection()永远不会被调用,因此无法自动滚动。
有什么建议吗?
3个回答

10

作为一种解决方法,我修改了滚动监听器...有些粗糙,但它完成了工作。

旧代码 - 在下面的编辑后找到新代码

    this.getListView().setOnScrollListener(new OnScrollListener() {
        public void onScroll(AbsListView view, int first, int visible, int total) {
            if (visible == 0 || visible < total && (first + visible == total) || (getListView().getTranscriptMode() == 2) && (first + visible == total)) {
                if (getListView().getTranscriptMode() != 2)
                    getListView().setTranscriptMode(2);
            } else {
                if (getListView().getTranscriptMode() != 0)
                    getListView().setTranscriptMode(0);
            }
        }

        public void onScrollStateChanged(AbsListView view, int scrollState) {}
    });

编辑 6/6/11:

我继续修改了这段代码,因为我发现自己的实现中存在一个UI bug(在我删除了我的alwaysScroll xml设置后,初始位置不再保持在底部)。我会保留上面的旧代码,但是这里是我现在正在使用的代码:

        getListView().setOnScrollListener(new OnScrollListener() {
            public void onScroll(AbsListView view, int first, int visible, int total) {
                    if (visible == 0 || visible == total || (first + visible == total) {
                        if (getListView().getTranscriptMode() != AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL)
                            getListView().setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
                    } else {
                        if (getListView().getTranscriptMode() != AbsListView.TRANSCRIPT_MODE_DISABLED)
                            getListView().setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);
                    }
            }

            public void onScrollStateChanged(AbsListView view, int scrollState) {}
        });

嗨,谢谢你,我也遇到了同样的问题,这个解决了 :) 快问一下,你在 XML 中是否留下了任何 transcriptMode 设置? - Al.
对于标记为“OLD CODE”的代码,我在XML中添加了transcriptMode设置,但是对于编辑后的代码,我没有这样做。(这就是我更改代码的原因,以删除我的初始XML设置) - BCS

-2

有一个更简单的解决方案。

lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

显然这必须在代码中完成。我找不到在布局文件中设置 TRANSCRIPT_MODE_ALWAYS_SCROLL 的方法。


2
虽然这样做可以工作,但这不是预期的行为。我希望它只在屏幕上显示最后一项时才滚动。如果用户向上滚动,我不希望视图重置到列表底部(因此需要解决方法)。 - BCS

-3

或者在XML布局中,

android:transcriptMode="alwaysScroll"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接