我遇到了listview和ArrayAdapter的问题。 我的目标是在每一行上都有一个按钮,允许用户隐藏(或显示)此行中包含的TextView。
但是当我测试我的代码时,如果我单击第一行的按钮,它会隐藏第一个TextView,还会隐藏下面的另一个TextView 9行。
我认为这是正常的回收机制操作,但我并不理解它,因为我认为在onClick方法上,View参数是唯一的。
adapter_test.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:padding="5dip">
<ImageButton
android:id="@+id/adapter_test_button_showhide"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:src="@drawable/ic_action_pause_light">
</ImageButton>
<!-- label -->
<TextView android:id="@+id/adapter_test_text_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf ="@id/adapter_test_button_showhide">
</TextView>
</RelativeLayout>
AdapterTest.java
public class AdapterTest extends ArrayAdapter<String>
{
// Holder
static class ViewHolder {TextView txtLabel ; ImageButton btnShowHide;}
//Initialize adapter
public AdapterTest(Context context, int resource, List<String> items) {super(context, resource, items);}
@Override
public View getView(int position, View v, ViewGroup parent)
{
// view Holder
ViewHolder viewHolder;
//Inflate the view
if(v==null)
{
//linearView = new LinearLayout(getContext());
LayoutInflater li = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.adapter_test, null);
// Create holder
viewHolder = new ViewHolder();
viewHolder.txtLabel = (TextView)v.findViewById(R.id.adapter_test_text_label);
viewHolder.btnShowHide = (ImageButton)v.findViewById(R.id.adapter_test_button_showhide);
v.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) v.getTag();
}
// Load screen with data;
LoadScreenFromItem (viewHolder,getItem(position));
return v;
}
public void LoadScreenFromItem(ViewHolder viewHolder, String item)
{
// Remove handler
viewHolder.btnShowHide.setOnClickListener(null);
// Add handler
viewHolder.btnShowHide.setOnClickListener(handleOnClickShowHide());
// Set textt
viewHolder.txtLabel.setText(item);
}
private View.OnClickListener handleOnClickShowHide()
{
return new View.OnClickListener()
{
public void onClick(View v)
{
View parent = (View)v.getParent();
TextView listserie = (TextView) parent.findViewById(R.id.adapter_test_text_label);
// hide or show label
if (listserie.isShown()) listserie.setVisibility(View.INVISIBLE);
else listserie.setVisibility(View.VISIBLE);
}
};
}
}
问题:
我的问题是:有办法做我想做的事吗?
答案 0 :(得分:2)
在代码中很难找到问题。
您正在重复使用ViewHolder
,这非常好,因为它可以节省您每次重新分配新内存的时间。
代码中的问题是:您没有重置TextView
的可见性,导致重用的View将继承任何其他TextView的可见性设置的问题。
为了解决这个问题,您必须将每个项目的可见性与项目本身一起存储在适配器中,并在恢复视图时重新加载可见性设置。
而不是String
我会使用
class AGoodClassName {
String s; boolean b;
}
哪个存储在适配器中。只要可见性发生变化,您就需要更新b
。
答案 1 :(得分:0)
旧线程,但它适用于我,因为我只需要在ListView的某些列表项中显示按钮。
如果有人指向此...这是我用来仅显示我列表中某些项目中的按钮的代码!
The problem in your code is: You are not resetting the visibility of the TextView, leading to the problem that a reused View will inherit the visibility settings of any other TextView.
记录我正在使用ButterKnife!
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = activity.getLayoutInflater().inflate(resource, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
if(items.size() > 0) {
MyItem item = items.get(position);
holder.myButton.setVisibility(View.VISIBLE);
if(!item.hasButton()) {
holder.myButton.setVisibility(View.GONE);
}
holder.myButton.setFocusable(false);
holder.myButton.setClickable(false);
}
return convertView;
}
public class ViewHolder {
@InjectView(R.id.card_btn_layout) View myButton;
public ViewHolder(View view) {
ButterKnife.inject(this, view);
}
}