2

我有一个列表视图和 ArrayAdapter 的问题。我的目标是在每一行上都有一个按钮,允许用户隐藏(或显示)该行中包含的 TextView。

但是当我测试我的代码时,如果我单击第一行的按钮,它会隐藏第一个 TextView 以及下面的另一个 TextView 9 行。

我想这是正常的回收机制操作,但我并没有真正理解它,因为我假设在 onClick 方法上, View 参数是唯一的。

适配器测试.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);   
          }
      };
  }
}

问题 :

我的问题是:有没有办法做我想做的事?

4

2 回答 2

2

这个问题很难在代码中找到。

您正在重用您的ViewHolder,这非常好,因为它可以节省您每次重新分配新内存的时间。

您的代码中的问题是:您没有重置 的可见性TextView,导致重用 View 将继承任何其他 TextView 的可见性设置的问题。

为了解决该错误,您必须将每个项目的可见性与项目本身一起存储在适配器中,并在恢复视图时重新加载可见性设置。

而不是String我会使用

class AGoodClassName {
String s; boolean b;
}

它存储在适配器中。b每当可见性发生变化时,您都需要更新。

于 2012-12-20T17:55:28.543 回答
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);
    }
}
于 2014-07-03T16:39:10.697 回答