gpt4 book ai didi

Android onlistclick 切换 listview 行高导致多个更改

转载 作者:太空狗 更新时间:2023-10-29 13:36:27 25 4
gpt4 key购买 nike

情况:

我的应用程序包含一个 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com