2012-12-20 33 views
2

我有一個listview和ArrayAdapter的問題。 我的目標是在每一行上都有一個按鈕,允許用戶隱藏(或顯示)該行所包含的TextView。Android Listview:按鈕來隱藏行中的控件

但是,當我測試我的代碼時,如果我點擊第一行的按鈕,它隱藏了第一個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); 
      } 
     }; 
    } 
} 

問:

我的問題是:有沒有辦法做我想做的?

回答

2

該問題在代碼中很難找到。

您正在重複使用您的ViewHolder,這非常好,因爲它可以節省您每次重新分配新內存的時間。

代碼中的問題是:您沒有重置TextView的可見性,導致重用的View將繼承任何其他TextView的可見性設置。

爲了解決這個問題,您必須將每個項目的可見性與項目本身一起存儲在適配器中,並在恢復視圖時重新加載可見性設置。

相反的String我會用一個

class AGoodClassName { 
String s; boolean b; 
} 

存儲在適配器。只要可見性發生變化,您就需要更新b

+0

謝謝直到它工作正常。 我只是有點困惑在我的項目中存儲一個用戶界面狀態,但它是可以接受的。 – Batrarri

+0

@Batrarri你可以將你的類分成數據和UI類,其中布爾值在UI類中。我不確定這裏最好的課程設計 – Till

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); 
    } 
}