我有一個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進行此操作)不展開/摺疊子視圖。