Android可扩展列表视图 - onClickListener,用于具有持久状态的子项内的按钮

时间:2012-10-09 15:06:57

标签: android android-listview expandablelistview

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

我以编程方式分配某一天的食物。每顿饭(标题是小组)是一个包含投票和订单按钮的孩子。当订餐时,两者都变为“订购”。如果另一个订单生成,则先前的订单按钮返回到“订单”状态,并且所选订单按顺序进行订购。投票也是如此。我通过在我的按钮上设置一个点击监听器来循环浏览所有其他按钮并将其文本设置为“order”/“vote”并将当前按钮文本设置为有序。

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

我相信它可能与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(在成功投票时实现按钮文字更改的类)

1 个答案:

答案 0 :(得分:2)

android上的listview工作效率的方式是它们实现了一种“视图回收”方法,如果某些视图离开屏幕,那么相同的视图会被放回到屏幕上的某个位置,所有必要的位都会被更改。这样可以节省大量资源,实际上重用相同的资源,但如果你需要像你一样坚持特定顺序的状态,那就会造成严重破坏。你应该做的是实现某种类型的map或arraylist,其中对象上的位置对应于listview的位置,然后通过make对象进行更改。有点蹩脚,但有点像适配器的适配器方法。

现在我道歉,因为我无法准确地想象出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]说“投票”,那么就这样做。

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