【问题标题】:ExpandableListView: wrong groupPosition returned if there's an expanded childViewExpandableListView:如果有展开的 childView,则返回错误的 groupPosition
【发布时间】:2014-05-09 16:40:29
【问题描述】:

我有一个 ExpandableListView;列表的单个项目(组项目)具有包含 ToggleButton 的 FrameLayout。我这样做是为了增加按钮的触摸区域。我使用按钮来展开它所属的组项的子视图。
一次不能有两个选中按钮,因为当一个被选中时,前一个被选中的按钮将被取消选中。
现在,当我第一次单击某个项目的按钮时,它可以切换;之后,当我单击另一项中的一项时,切换的按钮是位于“单击按钮的位置”+1 位置的按钮。
但是,如果我单击了最后一项的按钮,则将被切换的按钮是位于“当前切换按钮的位置”+1 位置的按钮(这意味着如果我首先切换项目 1,然后单击最后一项的按钮,第 2 项将切换;再次单击最后一项将切换第 3 项,然后是第 4 项、第 5 项,依此类推,直到最后一项将切换)。

这是适配器的代码:

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)。

【问题讨论】:

    标签: android expandablelistview togglebutton


    【解决方案1】:

    好的,这是一个非常蹩脚的错误。每次调用 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多