我正在使用CursorAdapter
来处理我的ListActivity
:
public class Mclass extends ListActivity{
...
TheAdapter mAdapter;
public static HashMap<Long, Boolean> shown = new HashMap<Long, Boolean>();
...
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Boolean tmp = shown.get(id);
if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
shown.put(id, true);
} else {
shown.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
}
mAdapter.notifyDataSetChanged();
}
}
和我的适配器类扩展CursorAdapter
并覆盖bindView
:
@Override
public void bindView(View view, Context context, Cursor cursor) {
String listText= cursor
.getString(cursor
.getColumnIndexOrThrow(DataHandler.MY_TEXT));
long id = cursor.getLong(cursor.getColumnIndexOrThrow(DataHandler.ROW_ID));
if (Mclass.shown.get(id) != null) {
TextView m_text = (TextView) view
.findViewById(R.id.my_text);
if (m_text != null) {
m_text.setVisibility(Mclass.shown.get(id)? View.VISIBLE:
View.GONE);
if (m_text.isShown())
m_text.setText("STRING");
}
}
我的列表项布局在xml文件list_item.xml
中定义:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#DDDDDD"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/my_image"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:paddingRight="1dip"
android:paddingTop="1dip"
</LinearLayout>
/*
*I want to toggle this text view's visibility
*/
<TextView
android:id="@+id/my_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"//VISIBILITY defined here
android:paddingBottom="2dip"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:paddingTop="5dip" />
</LinearLayout>
如何在TextView
内切换布局中onListItemClick
的展示率?
我试过了:
TextView mTextView = (TextView) v.findViewById(R.id.my_text);
mTextView.setVisibility(mTextView.isShown()? View.GONE: View.VISIBLE);
mAdapter.notifyDataSetChanged();
但它似乎是选择要随机切换的列表项,无论我点击哪一个。
答案 0 :(得分:3)
您必须存储要隐藏的行的ID。您可以在活动中创建一个字段来存储这些ID:
HashMap<Long, Boolean> positionHide = new HashMap<Long, Boolean>();
其中key是行的long id,boolean对象表示TextView
的状态(false-它消失了,true显示它是可见的)。在onListItemClick()
中,将点击的行的ID添加到该字段:
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Boolean tmp = positionHide.get(id);
if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
status.put(id, true);
} else {
status.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
}
mAdapter.notifyDataSetChanged();
}
还修改bindView()
方法:
@Override
public void bindView(View view, Context context, Cursor cursor) {
String listText = cursor.getString(cursor
.getColumnIndexOrThrow(DataHandler.MY_TEXT));
long pos = cursor.getLong(cursor.getColumnIndex(DataHandler.ID)); // DataHandler.ID will point to the column _id
TextView m_text = (TextView) view.findViewById(R.id.my_text);
if(status.get(pos) == null) {
//id is not yet in the hashmap so the value is
//by default false, the TextView is invisible
m_text.setVisibility(View.GONE);
} else {
// we have the value in the
// Hashmap so see what it is and set the
// textview visibility from this value
if (tmp.booleanValue()) {
m_text.setVisibility(View.VISIBLE);
} else {
m_text.setVisibility(View.GONE);
}
}
if (m_text != null)
m_text.setText(listText);
}
为此,您需要在数据库中添加_id INTEGER PRIMARY KEY AUTOINCREMENT
列(并添加到查询中)。
答案 1 :(得分:1)
您的问题是视图在列表视图中重用。这样即使你有一个由100个项目组成的列表,也只有10个左右的视图实例(取决于屏幕上可以安装多少个)。如果您可以看到方法bindView将视图重用为参数。
您所做的是采取了一个视图,例如显示列表中的第23个项目,并隐藏文本框。当第23个项目滚出屏幕时,它的视图会被重复使用,但只有值被第33个项目的数据替换,您为重复使用的视图设置的可见性和其他参数保持不变。
您应该做的是为所有列表项添加状态布尔值,并在适配器的bindView中根据项目当前所需的状态切换文本框可见性。
另一个重要的事情是,当您单击该项时,不会调用bindView方法。因此,您还应该在onClick方法中切换可见性,以使更改成为实例。如果你错过了这个,那么只有在项目滚动并再次滚动之后,视图的外观才会改变 - 这就是bindView检查可见性布尔值的时候。
向DataSetObservers通知“数据”中的更改会更加明智,让ListView为所有可见项调用bindView,但它也更耗费资源。
HashMap<Long, Boolean> positionHide = new HashMap<Long, Boolean>();
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Boolean tmp = positionHide.get(id);
if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
positionHide.put(id, true);
tmp = true;
} else {
tmp = !tmp.booleanValue();
positionHide.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
}
// You should also hide the text view, because bindView will not be called until the list item is scrolled out and in again
TextView m_text = (TextView) view.findViewById(R.id.my_text);
if (m_text != null) {
if(tmp) {
// We should hide the text view
m_text.setVisibility(View.GONE);
} else {
// We should display the text view
m_text.setVisibility(View.VISIBLE);
}
}
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
String listText = cursor.getString(cursor
.getColumnIndexOrThrow(DataHandler.MY_TEXT));
TextView m_text = (TextView) view.findViewById(R.id.my_text);
if (m_text != null) {
m_text.setText(listText);
long pos = cursor.getLong(cursor.getColumnIndex(DataHandler.ID)); // DataHandler.ID will point to the column _id
if((positionHide.get(pos) != null)&&(positionHide.get(pos))) {
// We should hide the text view
m_text.setVisibility(View.GONE);
} else {
// We should display the text view
m_text.setVisibility(View.VISIBLE);
}
}
}
为此,您需要在数据库中添加_id INTEGER PRIMARY KEY AUTOINCREMENT
列(并添加到查询中)。
答案 2 :(得分:1)
您不应该将ListView
用于任何有效的视图,请尝试使用TableLayout或LinearLayout。
请查看this blog帖子以获取更多详细信息,但是它适用于CheckBoxes,但对于任何活动视图都适用。