2

リストビューとArrayAdapterに問題があります。私の目的は、ユーザーがこの行に含まれるTextViewを非表示(または表示)できるようにするボタンを各行に配置することです。

しかし、コードをテストするときに、最初の行のボタンをクリックすると、最初のTextViewだけでなく、9行下の別のTextViewも非表示になります。

これは通常のリサイクルメカニズムの操作だと思いますが、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);   
          }
      };
  }
}

質問 :

私の質問は:私がやりたいことをする方法はありますか?

4

2 に答える 2

2

コード内で問題を見つけるのは非常に困難です。

ViewHolderこれは、毎回新しいメモリを再割り当てする時間を節約できるため、非常に優れています。

コードの問題は次のとおりです。の可視性をリセットしていないためTextView、再利用されたビューが他の 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 に答える