【发布时间】:2014-03-29 21:09:03
【问题描述】:
我正在构建一个类似于聊天的 Android 应用程序,类似于环聊。为此,我使用带有stackFromBottom=true 和transcriptMode="normal" 的垂直ListView。
列表从较早的消息(顶部)到较年轻的消息(底部)排序。正常状态下,ListView滚动到底部,显示最年轻的消息。
一旦用户滚动到列表顶部,ListView 使用反向无限滚动适配器加载更多(旧)消息。加载较旧的消息后,它们将被添加到列表顶部。
当旧消息添加到列表顶部时,所需的行为是 ListView 将其滚动位置保持在列表底部。也就是说,当旧消息添加到顶部时,滚动视图应该显示与添加旧消息之前相同的消息。
很遗憾,这不起作用。 ListView 不会将滚动位置保持在底部,而是将滚动位置保持在列表顶部。也就是说,将较旧的消息添加到列表后,列表会显示最顶部(即最旧)的消息。
有没有一种简单的方法来告诉 ListView 在向其顶部添加新项目时将其滚动位置保持在底部而不是顶部?
更新
出于演示目的,我已尽可能减少用例和代码。下面的示例创建一个简单的字符串数组列表。单击一个项目将在列表顶部添加另一个项目。长按一个项目将在列表底部添加另一个项目。
在列表底部添加项目时一切正常(长按)。在列表顶部添加项目时(简单点击),则有3种情况:
- 如果列表滚动到底部,则一切正常。将项目添加到顶部后,列表仍然滚动到底部。
- 如果列表没有滚动到底部(也没有滚动到顶部),则列表将保持其滚动位置(从顶部开始)。这使得列表看起来“跳”了一个项目。在这种情况下,我希望列表不要“向上跳跃”,即我希望它从底部保持滚动位置。
- 如果列表滚动到顶部,则会发生与情况 2 相同的情况。首选行为与情况 2 相同。
(最后2个case其实是一样的,我把它们分开是因为case 2可以更好的说明问题。)
代码
public class MyListActivity extends Activity {
int topIndex = 1;
int bottomIndex = 20;
protected final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_list_activity);
final ListView list = (ListView) findViewById(R.id.list);
list.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
list.setStackFromBottom(true);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1);
for (int i = topIndex; i <= bottomIndex; i++) {
adapter.add(Integer.toString(i));
}
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
adapter.insert(Integer.toString(--topIndex), 0);
}
});
list.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
adapter.add(Integer.toString(++bottomIndex));
return true;
}
});
}
}
【问题讨论】:
-
我相信你的意思是 android:stackFromBottom=true
-
是的,我愿意。已更正,谢谢。
-
您找到解决方案了吗?也在为此苦苦挣扎。
-
粗略查看源代码,这似乎是
AbsListView(与基础AdapterView相对)中经过深思熟虑的设计选择。它根据第一个/最后一个项目的 position 而不是 id 同步滚动状态。但是,如果它在报告数据集更改时选择了一个项目,那么它会根据 id 同步所选项目本身的滚动位置(无论ListAdapter是否具有稳定的 id)。 -
嗯,那么也许我需要在添加更多项目之前将一个项目设置为选中?
标签: android listview scroll endlessadapter