【问题标题】:Setting a button Activated in my listadapter also activates every 6th button below设置在我的列表适配器中激活的按钮也会激活下面的每 6 个按钮
【发布时间】:2013-07-25 08:50:49
【问题描述】:

我有一个显示客户请求的自定义 ListAdapter,每行有三个 ImageButton,允许您分别设置状态为 Completed、In Process 或 Cancel。 ImageButtons 设置为像单选按钮一样工作,每行只能激活一个,并且每个按钮都标记有 messageID 和所需的状态。

由于按钮被激活/停用,我从名为 AppInfo.messageButtons 的全局可用 Arraylist 中添加/删除它们。我稍后遍历 ArrayList 以确定要对哪些请求采取行动,以及应该执行哪些操作。按钮可以单击一次选择,再次单击取消选择。从我的 messageButtons 数组列表中的结果来看,这部分似乎工作正常。

我遇到的问题是 ImageButtons 在没有被点击的情况下获得激活状态。事实上,对于我激活的每个 ImageButton,在同一列中它下面的每 6 个按钮都会被激活,就好像它们是链接的一样。这与请求的数量无关。我已经完成了 6 个请求,我已经完成了 30 个请求。

例如,此图表描述了将请求 1 设置为“已完成”,将请求 3 设置为“取消”的结果。只有 2 次点击,但 5 个项目显示为已激活。只有最初单击的两个最终出现在我的 AppInfo.messageButtons 数组列表中,但如果我再次单击“请求 7 已完成”(以停用),它也会停用 1 和 13。因此,除了令人困惑之外,它还搞砸了标记消息。

            Complete   InProcess   Cancel
Request 1      X           -          -
Request 2      -           -          -
Request 3      -           -          X
Request 4      -           -          -
Request 5      -           -          -
Request 6      -           -          -
Request 7      X           -          -
Request 8      -           -          -
Request 9      -           -          X
Request 10     -           -          -
Request 11     -           -          -
Request 12     -           -          -
Request 13     X           -          -
Request 14     -           -          -

谁能解释一个按钮的 onClick 处理程序如何激活下面六行的按钮?为什么每 6 个按钮?这让我很困惑。

这是我的自定义适配器的代码:

public class EloquenceMessageAdapterStaff
        extends ArrayAdapter<GlobalMessage>
{
    ArrayList<GlobalMessage> roomMessages;

    public EloquenceMessageAdapterStaff(Context context, int textViewResourceId, ArrayList<GlobalMessage> roomMessages){
        super(context, textViewResourceId, roomMessages);

        this.roomMessages = roomMessages;

        int count = roomMessages.size();
        Log.i("Eloquence","roomMessages adapter count=" + Integer.toString(count) );
    }

    public View getView(int position, View convertView, ViewGroup parent){

        View v = convertView;

        if(v == null){
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.messagestaff, null);
        }

        GlobalMessage md = roomMessages.get(position);

        if (md != null) {

            int messageId = md.getId();
            String messageIdString = Integer.toString(messageId);
            String messageText= md.getText();
            Date messageTime = md.getInitiatedTime();
            PNMCode messagePnm = md.getPnmCode();
            String messageFullText = messagePnm.getFullText();


            TextView mp_text = (TextView) v.findViewById(R.id.mp_text);
            TextView mp_timedate = (TextView) v.findViewById(R.id.mp_timedate);

            DateFormat dateformat = new SimpleDateFormat("h:mm a, E d");
            String datetext = dateformat.format(messageTime);

            if (mp_text != null){
                mp_text.setText( messageFullText );
            }
            if (mp_timedate != null){
                mp_timedate.setText( datetext );
            }

            final ImageButton button_completed = (ImageButton) v.findViewById(R.id.button_messagestatus_Completed);
            final ImageButton button_inprocess = (ImageButton) v.findViewById(R.id.button_messagestatus_InProcess);
            final ImageButton button_cancel    = (ImageButton) v.findViewById(R.id.button_messagestatus_Cancel);

            button_completed.setTag(R.id.tag_message_id,messageIdString);
            button_completed.setTag(R.id.tag_message_status,"Completed");

            button_inprocess.setTag(R.id.tag_message_id,messageIdString);
            button_inprocess.setTag(R.id.tag_message_status,"InProcess");

            button_cancel.setTag(R.id.tag_message_id,messageIdString);
            button_cancel.setTag(R.id.tag_message_status,"Canceled");


            button_completed.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    if ( button_completed.isActivated() ) {
                        AppInfo.messageButtons.remove(button_completed);
                        button_completed.setActivated(false);
                    } else {
                        AppInfo.messageButtons.add(button_completed);
                        button_completed.setActivated(false);
                        button_inprocess.setActivated(false);
                        button_cancel.setActivated(false);
                        button_completed.setActivated(true);
                    }
                }
            });
            button_inprocess.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    if ( button_inprocess.isActivated() ) {
                        AppInfo.messageButtons.remove(button_inprocess);
                        button_inprocess.setActivated(false);
                    } else {
                        AppInfo.messageButtons.add(button_inprocess);
                        button_completed.setActivated(false);
                        button_inprocess.setActivated(false);
                        button_cancel.setActivated(false);
                        button_inprocess.setActivated(true);
                    }
                }
            });
            button_cancel.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    if ( button_cancel.isActivated() ) {
                        AppInfo.messageButtons.remove(button_cancel);
                        button_cancel.setActivated(false);
                    } else {
                        AppInfo.messageButtons.add(button_cancel);
                        button_completed.setActivated(false);
                        button_inprocess.setActivated(false);
                        button_cancel.setActivated(false);
                        button_cancel.setActivated(true);
                    }
                }
            });
        }
        return v;
    }
}

这是我的主要布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="5dp"
    android:paddingBottom="5dp"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    >
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />
    <TextView
        android:id="@android:id/empty"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text=""
        />
</LinearLayout>

这是我的行布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp"
>
    <TextView
        android:id="@+id/mp_timedate"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:text=""
        android:layout_alignParentLeft="true"
        />
    <TextView
        android:id="@+id/mp_text"
        android:layout_width="336dp"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:text=""
        android:layout_toRightOf="@id/mp_timedate"
        />
    <ImageButton android:id="@+id/button_messagestatus_Completed"
        style="@style/buttontight"
        android:src="@drawable/ic_menu_mark"
        android:layout_toRightOf="@id/mp_text"
        android:contentDescription="Mark message completed"
        />
    <ImageButton android:id="@+id/button_messagestatus_InProcess"
        style="@style/buttontight"
        android:src="@drawable/ic_menu_stopwatch"
        android:layout_toRightOf="@id/button_messagestatus_Completed"
        android:contentDescription="Mark message In Process"
        />
    <ImageButton android:id="@+id/button_messagestatus_Cancel"
        style="@style/buttontight"
        android:src="@drawable/ic_menu_block"
        android:layout_toRightOf="@id/button_messagestatus_InProcess"
        android:contentDescription="Mark message cancelled"
        />
</RelativeLayout>

【问题讨论】:

标签: android listadapter


【解决方案1】:

ListView 中的视图被回收。因此,即使您的列表中有 14 个项目,实际上也只创建了 6 个视图(行)。这就是 convertView 发挥作用的地方。如果您的适配器使用 convertView,这意味着它使用的 View 已经设置了另一个项目的信息。问题在于,转换后的视图的按钮正在维护绑定到它的上一个项目的状态。因此,在 getView 中,您需要做一些事情来设置按钮的状态以匹配它们所代表的 GlobalMessage。

【讨论】:

  • 好的,我已经阅读了关于视图回收的内容,我明白你在说什么。行的重用意味着您不能在视图中存储状态,即使是暂时的。我需要将所选内容的存储移动到数据模型中。这样,当视图被回收时,它们将保证显示正确的信息。
猜你喜欢
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多