- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
情况:
我的应用程序包含一个 ToDo 列表样式的 ListView (每行都有一个复选框)。 ListView 行由2 个垂直 布局的 TextView 组成。最上面的文本是标题,最下面的是描述,但是描述是隐藏的 (View.GONE)。使用 ListActivities onListItemClick 方法,我可以设置按下行的高度和可见性。
@Override
protected void onListItemClick(ListView list, View view, int position, long id) {
super.onListItemClick(list, view, position, id);
view.getLayoutParams().height = 200;
view.requestLayout();
TextView desc = (TextView) view.findViewById(R.id.description);
desc.setVisibility(View.VISIBLE);
}
注意:代码被剥离到最基本的部分
上面的代码工作正常,除了它扩展了按下的行以及上面或下面的第 10 行(下一个卸载 View ?)。当列表被抛出时,行扩展也会改变位置。
背景:
ListView 数据通过托管游标从 SQLite 数据库中检索,并由自定义 CursorAdapter 设置。托管游标按复选框值排序。
private void updateList() {
todoCursor = managedQuery(TaskContentProvider.CONTENT_URI, projection, null, null, TaskSQLDatabase.COL_DONE + " ASC");
startManagingCursor(todoCursor);
adapter = new TaskListAdapter(this, todoCursor);
taskList.setAdapter(adapter);
}
CursorAdapter 由基本的 newView() 和 bindView() 组成。
问题:
我需要一些系统来跟踪扩展了哪些行。我试过将游标 ID 存储在数组中,然后在适配器中检查是否应该扩展行,但我似乎无法让它工作。任何建议将不胜感激!
最佳答案
ListView
将在您上下滚动时回收 View ,当它需要一个新的子 View
来显示时,它会首先查看它是否还没有有一个(如果它找到一个它会使用它)。如果像以前那样(在 onListItemClick()
方法中)修改 ListView
的子项,然后滚动列表,ListView
最终将最终重用你修改过的那个子 View
,你最终会在你不想要的位置得到某些 View (如果你继续滚动 ListView
你由于 View
回收,您会看到随机位置发生变化)。
防止这种情况的一种方法是记住用户单击的那些位置,并在适配器中更改该特定行的布局,但仅限于您想要的位置。您可以将这些 ids
存储在 HashMap
(类中的一个字段)中:
private HashMap<Long, Boolean> status = new HashMap<Long, Boolean>();
我使用了一个HashMap
,但你可以使用其他容器(在下面的代码中你会看到为什么我选择了一个HashMap
)。接下来在 onListItemClick()
方法中,您将更改被点击的行,但也会存储该行 id
以便适配器知道(并采取措施,这样您就不会结束处理错误的回收 View ):
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// check and see if this row id isn't already in the status container,
// if it is then the row is already set, if it isn't we setup the row and put the id
// in the status container so the adapter will know what to do
// with this particular row
if (status.get(id) == null) {
status.put(id, true);
v.getLayoutParams().height = 200;
v.requestLayout();
TextView d = (TextView) v.findViewById(R.id.description);
d.setVisibility(View.VISIBLE);
}
}
然后在适配器中使用带有所有 ids
的状态容器来正确设置行并防止回收弄乱我们的行:
private class CustomAdapter extends CursorAdapter {
private LayoutInflater mInflater;
public CustomAdapter(Context context, Cursor c) {
super(context, c);
mInflater = LayoutInflater.from(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView title = (TextView) view.findViewById(R.id.title);
title.setText(cursor.getString(cursor.getColumnIndex("name")));
TextView description = (TextView) view
.findViewById(R.id.description);
description.setText(cursor.getString(cursor
.getColumnIndex("description")));
// get the id for this row from the cursor
long rowId = cursor.getLong(cursor.getColumnIndex("_id"));
// if we don't have this rowId in the status container then we explicitly
// hide the TextView and setup the row to the default
if (status.get(rowId) == null) {
description.setVisibility(View.GONE);
// this is required because you could have a recycled row that has its
// height set to 200 and the description TextView visible
view.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT,
AbsListView.LayoutParams.MATCH_PARENT));
} else {
// if we have the id in the status container then the row was clicked and
// we setup the row with the TextView visible and the height we want
description.setVisibility(View.VISIBLE);
view.getLayoutParams().height = 200;
view.requestLayout();
// this part is required because you did show the row in the onListItemClick
// but it will be lost if you scroll the list and then come back
}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = mInflater.inflate(R.layout.adapters_showingviews, null);
return v;
}
}
如果你想切换点击的行(有些东西告诉我你想要这个),在点击时显示 TextView
/在点击时隐藏 TextView
单击了另一行 然后简单地将 else 子句
添加到 onListItemClick()
方法并从状态容器中删除单击的行 id
并恢复该行:
//...
else {
status.remove(id);
v.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT,
AbsListView.LayoutParams.MATCH_PARENT));
TextView d = (TextView) v.findViewById(R.id.description);
d.setVisibility(View.GONE);
}
关于Android onlistclick 切换 listview 行高导致多个更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9951762/
情况: 我的应用程序包含一个 ToDo 列表样式的 ListView (每行都有一个复选框)。 ListView 行由2 个垂直 布局的 TextView 组成。最上面的文本是标题,最下面的是描述,但
我是一名优秀的程序员,十分优秀!