ListView onClick听众混淆了

时间:2014-01-17 09:36:16

标签: android android-listview

我的listview中有一个带有ImageView的项目。当我单击第一行行中的ImageView时,也会点击第四行项。为什么onClick搞砸了?我对每个项目的每个按钮都有new OnClickListener()吗?

public View getView(int position, View convertView, ViewGroup parent) {
            final BuddyViewHolder viewHolder;
            if (convertView == null || convertView.getTag() == null) {
                convertView = inflater.inflate(R.layout.buddy, null);
                viewHolder = new BuddyViewHolder();
                allBuddiesViewHolder.add(position, viewHolder) ;

                viewHolder.position = position;
                viewHolder.root = (LinearLayout) convertView
                        .findViewById(R.id.root);
                            viewHolder.request = (ImageView) convertView
                    .findViewById(R.id.request);

                //removed all other viewholder init's
                viewHolder.request.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (selectedBuddy == NO_BUDDY_SELECTED) {
                            viewHolder.request.setVisibility(View.GONE);
                            viewHolder.cancel.setVisibility(View.VISIBLE);
                            viewHolder.root.setSelected(true);
                            selectedBuddy = viewHolder.position;
                        } else {
                            Toast.makeText(context,
                                    "You can make only one request at a time.",
                                    Toast.LENGTH_LONG).show();
                        }
                    }
                });

                convertView.setTag(viewHolder);
            } else
                viewHolder = (BuddyViewHolder) convertView.getTag();

            // here I am setting the values from a arraylist
                    String company = allBuddies.get(position).emailId.substring(
                    allBuddies.get(position).emailId.indexOf("@"),
                    allBuddies.get(position).emailId.indexOf("."));
            viewHolder.name.setText(allBuddies.get(position).name);
            viewHolder.company.setText(company.toLowerCase());
            //removed some lines here.
            return convertView;
        }

ListView XML

 <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_weight="1"
            android:background="@drawable/roundcornersgreyback"
            android:descendantFocusability="blocksDescendants"
            android:divider="#ffffff"
            android:dividerHeight="5dp"
            android:duplicateParentState="true"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            android:scrollbarSize="3dp"
            android:scrollbarStyle="outsideOverlay"
            android:scrollbars="vertical"
            android:scrollingCache="true"
            android:smoothScrollbar="true" />

项目布局(好友)(仅限相关的ImageView)

 <ImageView
        android:id="@+id/request"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="3"
        android:adjustViewBounds="true"
        android:background="@drawable/roundcornerblue_button"
        android:enabled="true"
        android:src="@drawable/button_request"
        android:visibility="visible" />

根本原因

@fasteque

是的,我猜这个问题与Android提供的“行重用”机制有关。当convertView不为null时,您将返回一个已经设置了侦听器的视图(但它用于另一行)。为了确保这一点,禁用viewHolder模式,每次只创建一个新视图:我想它会起作用。然后,如果是这样,请按照上面的建议移动onClickListener。

修正

  1. 在initView(if / else)
  2. 初始化后添加了这些行
  3. 在我的内联onClick
  4. 中设置allBuddies.get(position).isRequestSent = true

    我的印象

    OnItemClickListener方式需要大量的黑客攻击。在这个特殊情况下,我更喜欢内联onClick。

    if (allBuddies.get(position).isRequestSent) {
                    viewHolder.cancel.setVisibility(View.VISIBLE);
                    viewHolder.request.setVisibility(View.GONE);
                    viewHolder.confirm.setVisibility(View.GONE);
                } else {
                    viewHolder.request.setVisibility(View.VISIBLE);
                    viewHolder.cancel.setVisibility(View.GONE);
                    viewHolder.confirm.setVisibility(View.GONE);
                }
    

1 个答案:

答案 0 :(得分:1)

我猜这个问题与Android提供的“行重用”机制有关。当convertView不为null时,您将返回一个已经设置了侦听器的视图(但它用于另一行)。

要确定这一点,请尝试此测试:禁用viewHolder模式,每次只创建一个新视图。我认为它会奏效。

然后,如果是这样,请按照第一条评论的建议将onClickListener移到convertView == null块之外。