Android Expandable List View - onClickListener for buttons within the child with persistent states

♀尐吖头ヾ 提交于 2020-01-11 09:47:07

问题


I am currently having an issue with the creation of my ExpandableListView. I'm unsure what is happening at the moment but I'll explain what I'm trying to do.

I programmatically allocate meals that fall on a certain day. Within each meal (the title is the group) is a child that contains a vote and order button. Both of which are changed to "Ordered" when a order is made on a meal. If another order is made the previous order button goes back to the 'order' state and the selected one goes to ordered. This is the same for vote. I go about this by setting an on click listener to my buttons that loop through all the other buttons and set their text to 'order'/'vote' and set the current buttons text to ordered.

This works fine in some extremely rare cases - but most of the time when I order/vote for an item it changes the selected one to 'ordered' and the last element in my expandable list view to ordered as well. Then if I order, lets say the 3rd element, close and reopen the second element it also changes to ordered and visa versa. Sometimes they all change back to order or all change to ordered. I'm finding it difficult to work out why this may be happening.

I believe it may have something to do with the getChildView function. As when I traverse through the list opening each element the view is never set for the last element even though it has been allocated the appropriate data.

Am I misunderstanding a major concept of the ExpandableListView or is there something else.

Here is the getChildView function that I believe there may be a fault. I'll also supply links to the other relevant classes below. If you need further information, please don't hesitate to ask.

//Static class view holder
static class ViewHolder {
    protected Button oBut;
    protected Button vBut;
    protected TextView description;
}

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    //Getting the appropriate child for the group and position
    ExpandListChild child = (ExpandListChild) getChild(groupPosition, childPosition);

    View view = null;

    //Set up if doesn't exist
    if (convertView == null) {
        Log.d("OnClickListener", "groupPosition: " + groupPosition + " childPosition: " + childPosition);
        Log.d("OnClickListener", "View being set up for: " + child.getName() + " desc: " + child.getDescription());

        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
        view = infalInflater.inflate(R.layout.expandlist_child_item_todays, null);

        //Attempt at viewholder
        final ViewHolder holder = new ViewHolder();
        holder.description = (TextView) view.findViewById(R.id.mealDescription);
        holder.vBut = (Button)view.findViewById(R.id.vote);
        holder.oBut = (Button)view.findViewById(R.id.order);

        view.setTag(holder);
    }
    else {
        view = convertView;
    }

    ViewHolder holder = (ViewHolder) view.getTag();

    holder.description.setText(child.getDescription());
    holder.description.setTag(child.getTag());

    holder.oBut.setOnClickListener(new OrderOnClick(groups, (Activity)context, holder.oBut, view, child));
    holder.vBut.setOnClickListener(new VoteOnClick(groups, (Activity)context, holder.vBut, view, child));

    return view;
}

ExpandListAdapterTodays (extends and extends off my BaseExpandableListAdapter)

ExpandListAdapter (extends the BaseExpandableListAdapter)

VoteOnClick (Class that implements the changing of button text when a successfull vote has been placed)


回答1:


the way that listviews on android work to be efficient is that they implement a "view recycling" method where if some view goes off screen, that same view is put back somewhere on the screen with all the necessary bits changed. That keeps things using much less resources, actually reusing the same resources, but wreaks havoc if you need states persisting in a specific order like you do. What you should do is to implement some sort of map or arraylist of which the position on the object corresponds to its position of the listview and then make changes through the made object. A little lame but its kinda like an adapter method for your adapter.

Now i apologize because i can't exactly visualize how the onlick method is supposed to work, but looking through it.. something like:

for (int i = 0; i < groups.size(); i++) {
....
but.setText("Vote");

would become

ArrayList<String> group_string_states = new ArrayList<String> ();

private void fillGroupStringStates () {
        for(int i = 0; i < groups.length; i++) {
            group_string_states.add("Order");
        }
    }

....

for (int i = 0; i < group_string_states.size(); i++) {
....
group_string_states.set(i, "Vote");

Then you do a conditional, like if group_string_states.get[position] says "vote", then do this.

Well, that's how i'd attempt to do it. i hope it helped and i'm really sorry if it didn't.



来源:https://stackoverflow.com/questions/12803064/android-expandable-list-view-onclicklistener-for-buttons-within-the-child-with

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!