我正在构建类似聊天的Android应用程序,类似于环聊.为此,我使用带有stackFromBottom=true和的垂直ListView transcriptMode="normal".
该列表从较旧的消息(顶部)到较年轻的消息(底部)排序.在正常状态下,ListView会滚动到底部,显示最年轻的消息.
一旦用户滚动到列表顶部,ListView使用反向无限滚动适配器来加载更多(较旧的)消息.加载旧邮件后,它们将添加到列表顶部.
所需的行为是,当旧消息添加到其顶部时,ListView将其滚动位置保持在列表的底部.也就是说,当较旧的消息添加到顶部时,滚动视图应显示在添加旧消息之前显示的相同消息.
不幸的是,这不起作用.ListView不是将滚动位置保持在底部,而是将滚动位置保持在列表顶部.也就是说,在将较旧的消息添加到列表之后,该列表显示最顶层(即最旧的)消息.
在将新项目添加到顶部时,是否有一种简单的方法可以告诉ListView将其滚动位置保持在底部而不是顶部?
更新
出于演示目的,我尽可能地减少了用例和代码.以下示例创建一个简单的字符串数组列表.单击某个项目将在列表顶部添加另一个项目.长按单击某个项目将在列表底部添加另一个项目.
在列表底部添加项目时,一切正常(长按).在列表顶部添加项目(简单点击),则有3种情况:
(最后两个案例实际上是相同的.我把它们分开了,因为在案例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<?> …Run Code Online (Sandbox Code Playgroud) getValues()当在没有显式类型参数的情况下调用函数时,以下 Typescript 代码可以正常工作。但是,当使用显式类型参数调用它时,可能会导致错误(请参阅getValues<'a' | 'b' | 'c' >(store, 'a', 'b')下面的调用)。
type Store = Record<string, string>;
function getValues<T extends string>(
store: Store, ...keys: T[]
): {[P in T]: string} {
const values = {} as {[P in T]: string};
keys.forEach((p) => {
const value = store[p];
if (value) {
values[p] = value;
} else {
values[p] = 'no value';
}
});
return values;
}
// Usage / requirements:
const store: Store = {}; // assume it is filled …Run Code Online (Sandbox Code Playgroud)