2014-05-09 36 views
1

我有一個ExpandableListView;列表的單個項目(組項目)具有包含ToggleButton的FrameLayout。我這樣做是爲了增加按鈕的觸摸面積。我使用該按鈕來展開它所屬組項的子視圖。
一次不能有兩個選中的按鈕,因爲當一個被選中時,前一個被選中的按鈕會被取消選中。
現在,我第一次點擊一個項目的按鈕時,它會正常切換;之後,我點擊另一個項目的其中一個,切換的按鈕是位於「單擊按鈕位置」+1的位置。
但是,如果我點擊了最後一個項目的按鈕,將被切換的按鈕位於「當前切換按鈕的位置」+1(這意味着如果我第一次切換項目1,然後點擊最後一個項目的按鈕,項目2將切換;再次點擊最後一項將切換項目3,然後項目4,項目5等等,最後,最後一個項目將切換)。ExpandableListView:如果有擴展的子視圖,返回錯誤的groupPosition

這裏的適配器代碼:

public class CustomList extends BaseExpandableListAdapter { 

private final Activity context; 
public List<Item> names;//Item is a custom object 
public boolean[] buttons; 
public int lastChecked; 
private final int imageId = R.drawable.item1; 
private ExpandableListView list; 

public CustomList(Activity context, List<Item> names, ExpandableListView theListView) { 

    this.context = context; 
    this.names = names; 
    this.buttons = new boolean[names.size()]; 
    this.lastChecked = -1; 
    this.list = theListView; 
} 

private static class GroupHolder { 

    TextView txtTitle; 
    TextView txtData; 
    ImageView imageView; 
    ToggleButton toggle; 
    FrameLayout frame; 
} 

public View getGroupView(final int position, boolean isExpanded, View convertView, ViewGroup parent) { 

    GroupHolder holder; 

    if (convertView == null) { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = inflater.inflate(R.layout.list_single, null); 

     holder = new GroupHolder(); 

     holder.txtTitle = (TextView) convertView.findViewById(R.id.text); 
     holder.txtData = (TextView) convertView.findViewById(R.id.numberOfFiles); 
     holder.imageView = (ImageView) convertView.findViewById(R.id.img); 
     holder.toggle = (ToggleButton) convertView.findViewById(R.id.toggle); 
     holder.frame = (FrameLayout) convertView.findViewById(R.id.frame); 

     holder.frame.setOnTouchListener(new OnTouchListener() { 

      public boolean onTouch(View v, MotionEvent event) { 

       if(event.getAction() == MotionEvent.ACTION_UP) { 

        if(lastChecked != -1) {//if there's a checked button 
         buttons[lastChecked] = !buttons[lastChecked];//uncheck it 

        if(position == lastChecked)//if I clicked on the last checked button 
         lastChecked = -1;//there's no checked button 
        else { 
         buttons[position] = !buttons[position];//check the button 
         lastChecked = position;//and set it as the last checked one 
        } 

        notifyList(); 
       } 

       return false; 
      }   
     }); 

     convertView.setTag(holder); 

    } else { 

     holder = (GroupHolder) convertView.getTag(); 
    } 

    holder.txtTitle.setText(names.get(position).getName()); 

    holder.txtData.setText(names.get(position).getData()); 

    holder.imageView.setImageResource(imageId); 

    holder.toggle.setChecked(buttons[position]); 

    if(holder.toggle.isChecked()) { 

     if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2) 
      list.expandGroup(position); 
     else 
      list.expandGroup(position, true); 
    } else { 

     list.collapseGroup(position); 
    } 

    return convertView; 
} 

private static class ChildHolder { 

    TextView details; 
    TextView send; 
    TextView other; 
} 

public View getChildView(final int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { 

    ChildHolder holder; 

    if (convertView == null) { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = inflater.inflate(R.layout.list_child, null); 

     holder = new ChildHolder(); 

     holder.details = (TextView) convertView.findViewById(R.id.details); 
     holder.send = (TextView) convertView.findViewById(R.id.send); 
     holder.other = (TextView) convertView.findViewById(R.id.other); 

     convertView.setTag(holder); 

    } else { 

     holder = (ChildHolder) convertView.getTag(); 
    } 

    holder.details.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 

      buttons[lastChecked] = !buttons[lastChecked];//uncheck the only checked button (it always exists at this point) 
      lastChecked = -1;//there's no checked button 

      notifyList(); 
      //*call some method in the main activity* 
     } 
    }); 

    holder.send.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 

      buttons[lastChecked] = !buttons[lastChecked];//uncheck the only checked button (it always exists at this point) 
      lastChecked = -1;//there's no checked button 

      notifyList(); 
      //*call some method in the main activity* 
     } 
    }); 

    holder.other.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 

      buttons[lastChecked] = !buttons[lastChecked];//uncheck the only checked button (it always exists at this point) 
      lastChecked = -1;//there's no checked button 

      notifyList(); 
      //*call some method in the main activity* 
     } 
    }); 

    return convertView; 
} 

public void notifyList() { 

    this.notifyDataSetChanged(); 
} 

正如你所看到的,在getGroupView,子項被展開或摺疊取決於項目的對應位置的布爾數組中的值,其在列表中查看。我調用notifyDataSetChanged()來更新列表。
在主要活動中,我將onGroupClickListener設置爲ExpandableListView,並在onGroupClick中返回true,以便在單擊組項時(因爲我使用ToggleButtons進行此操作)不展開/摺疊子視圖。

回答

2

好吧,這是一個非常蹩腳的錯誤。每次調用getGroupView時,我都必須爲FrameLayout設置OnTouchListener,而不僅僅是第一次。所以該方法的正確代碼是這樣的:

public View getGroupView(final int position, boolean isExpanded, View convertView, ViewGroup parent) { 

    GroupHolder holder; 

    if (convertView == null) { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = inflater.inflate(R.layout.list_single, null); 

     holder = new GroupHolder(); 

     holder.txtTitle = (TextView) convertView.findViewById(R.id.text); 
     holder.txtData = (TextView) convertView.findViewById(R.id.numberOfFiles); 
     holder.imageView = (ImageView) convertView.findViewById(R.id.img); 
     holder.toggle = (ToggleButton) convertView.findViewById(R.id.toggle); 
     holder.frame = (FrameLayout) convertView.findViewById(R.id.frame); 

     convertView.setTag(holder); 

    } else { 

     holder = (GroupHolder) convertView.getTag(); 
    } 

    holder.txtTitle.setText(names.get(position).getName()); 

    holder.txtData.setText(names.get(position).getData()); 

    holder.imageView.setImageResource(imageId); 

    holder.frame.setOnTouchListener(new OnTouchListener() { 

     public boolean onTouch(View v, MotionEvent event) { 

      if(event.getAction() == MotionEvent.ACTION_UP) { 

       if(lastChecked != -1) {//if there's a checked button 
        buttons[lastChecked] = !buttons[lastChecked];//uncheck it 

       if(position == lastChecked)//if I clicked on the last checked button 
        lastChecked = -1;//there's no checked button 
       else { 
        buttons[position] = !buttons[position];//check the button 
        lastChecked = position;//and set it as the last checked one 
       } 

       notifyList(); 
      } 

      return false; 
     } 
    }); 

    holder.toggle.setChecked(buttons[position]); 

    if(holder.toggle.isChecked()) { 

     if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2) 
      list.expandGroup(position); 
     else 
      list.expandGroup(position, true); 
    } else { 

     list.collapseGroup(position); 
    } 

    return convertView; 
} 
相關問題