我通过使用列表片段扩展AsyncTaskLoader来使用SQLiteCursorLoader,我设法通过保存位置和视图来保留新数据的位置,然后使用setSelectionFromTop(),这非常正常。
这就是它目前的工作方式,
光标重载前的数据库,
Field1 int, timestamp long
------------------
First row, now
Second row, 1 minute ago
Third row, 2 minutes ago -----> user is currently on this item in the listview
光标重载后的数据库
Field1 int, timestamp long
------------------
Fourth row, now
First row, 30 secon ago
Second row, 1 minute + 30 seconds ago
Third row, 2 minutes + 30 seconds ago --> go here using setSelectionFromTop(position, y)
光标重新加载后,我保留"第三行"的位置。因为我保存旧位置, 所以我需要做的就是计算旧位置 - 新光标数
现在我有一个新的要求(如下所示),不仅会有新数据进入,而且旧数据也会发生变化,这会使位置变得混乱,旧数据的时间戳会发生什么变化,所以结果SQLiteCursorLoader中使用的查询会有所不同,我不能再使用旧方法了。
Field1 int, timestamp long
------------------
First row, now
Second row, 1 minute ago
Third row, 2 minutes ago -----> user is currently on this item in the listview
光标重载后的数据库
Field1 int, timestamp long
------------------
Third row, now
First row, 30 secon ago
Second row, 1 minute + 30 seconds ago
正如您所看到的,现在的位置不会相同。现在我必须使用getItemId获取DB id并保存它,当光标重新加载时,我将不得不通过它来获得它的位置。
我的问题是,是否有可能以另一种/更快的方式做到这一点?
如果您需要更多说明,请与我们联系。
答案 0 :(得分:0)
这个解决方案有选择地阻止ListView布局它的孩子。为什么它不保留它的位置是ListView布置它的孩子在旧位置显示新项目。如果我们停止子布局通过,我们就会停止可见的位置变化。
制作一个像这样的cutom Listview小部件:
public class BlockingListView extends ListView {
private boolean mBlockLayoutChildren;
public BlockingListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setBlockLayoutChildren(boolean block) {
mBlockLayoutChildren = block;
}
@Override
protected void layoutChildren() {
if (!mBlockLayoutChildren) {
super.layoutChildren();
}
}
}
并像这样使用这个新的小部件..
int firstVisPos = mListView.getFirstVisiblePosition();
View firstVisView = mListView.getChildAt(0);
int top = firstVisView != null ? firstVisView.getTop() : 0;
// Block children layout for now
mListView.setBlockLayoutChildren(true);
// Number of items added before the first visible item
int itemsAddedBeforeFirstVisible = ...;
// Change the cursor, or call notifyDataSetChanged() if not using a Cursor
mAdapter.swapCursor(...);
// Let ListView start laying out children again
mListView.setBlockLayoutChildren(false);
// Call setSelectionFromTop to change the ListView position
mListView.setSelectionFromTop(firstVisPos + itemsAddedBeforeFirstVisible, top);