2

我目前在创建 ExpandableListView 时遇到问题。我不确定目前发生了什么,但我会解释我正在尝试做的事情。

我以编程方式分配某一天的膳食。每顿饭(标题是组)中都有一个包含投票和订购按钮的子项。点餐时,两者都更改为“已订购”。如果下一个订单,前一个订单按钮将返回到“订单”状态,而选中的订单将变为已订购。这与投票相同。我通过为我的按钮设置一个点击监听器来解决这个问题,该按钮循环遍历所有其他按钮并将它们的文本设置为“order”/“vote”并将当前按钮的文本设置为有序。

这在一些极其罕见的情况下可以正常工作 - 但大多数情况下,当我为某个项目订购/投票时,它会将选定的项目更改为“已订购”,并将可扩展列表视图中的最后一个元素也更改为已订购。然后,如果我订购,比如说第三个元素,关闭并重新打开第二个元素,它也会变为有序,反之亦然。有时他们都改回订单或全部更改为已订购。我发现很难弄清楚为什么会发生这种情况。

我相信这可能与 getChildView 函数有关。当我遍历打开每个元素的列表时,即使已为其分配了适当的数据,也永远不会为最后一个元素设置视图。

我误解了 ExpandableListView 的一个主要概念还是有别的什么。

这是我认为可能有错误的getChildView函数。我还将在下面提供其他相关课程的链接。如果您需要更多信息,请随时询问。

//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(扩展和扩展我的 BaseExpandableListAdapter)

ExpandListAdapter(扩展 BaseExpandableListAdapter)

VoteOnClick(实现在成功投票时更改按钮文本的类)

4

1 回答 1

2

android 上的 listview 高效工作的方式是它们实现了“视图回收”方法,如果某些视图离开屏幕,则相同的视图将放回屏幕上的某个位置,所有必要的位都已更改。这使事情使用更少的资源,实际上重用了相同的资源,但是如果您需要像您一样以特定顺序持续存在的状态,则会造成严重破坏。您应该做的是实现某种映射或数组列表,其中对象上的位置对应于列表视图的位置,然后通过制作的对象进行更改。有点蹩脚,但它有点像适配器的适配器方法。

现在我道歉,因为我无法准确地想象 onlick 方法应该如何工作,但是通过它查看..类似于:

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

会成为

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

然后你做一个条件,比如如果 group_string_states.get[position] 说“投票”,然后这样做。

好吧,这就是我尝试这样做的方式。我希望它有所帮助,如果没有,我真的很抱歉。

于 2012-10-09T15:41:31.220 回答