【问题标题】:onClick fired, but does not get right listview itemonClick 被触发,但没有得到正确的列表视图项
【发布时间】:2016-01-27 15:11:59
【问题描述】:

我的列表视图项目有这个布局:

    <?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="wrap_content"
    android:layout_gravity="center_horizontal"
    android:padding="10dp">

    <ImageView
        android:id="@+id/cartIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginRight="10dp"
        android:onClick="addToCartClick"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/itemName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_toRightOf="@id/cartIcon"
        android:text="Filé Mignon"
        android:textAppearance="@android:style/TextAppearance.Small"
        android:typeface="normal" />

    <TableLayout
        android:id="@+id/tableInfo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/itemName"
        android:layout_toRightOf="@id/cartIcon"
        android:weightSum="3">

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/qtyText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Qtd"
                android:textAlignment="center"
                android:textAppearance="?android:attr/textAppearanceSmall" />

            <TextView
                android:id="@+id/priceText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Preço"
                android:textAlignment="center"
                android:textAppearance="?android:attr/textAppearanceSmall" />

            <TextView
                android:id="@+id/totalText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Total"
                android:textAlignment="center"
                android:textAppearance="?android:attr/textAppearanceSmall" />

        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/qty"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="2 Kg"
                android:textAlignment="center"
                android:textAppearance="?android:attr/textAppearanceSmall" />

            <TextView
                android:id="@+id/price"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="R$ 75,00"
                android:textAlignment="center"
                android:textAppearance="?android:attr/textAppearanceSmall" />

            <TextView
                android:id="@+id/total"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="R$ 150,00"
                android:textAlignment="center"
                android:textAppearance="?android:attr/textAppearanceSmall" />

        </TableRow>
    </TableLayout>

</RelativeLayout>

对于 ImageView 的 onClick 方法:

android:onClick="addToCartClick"

点击 ImageView 但未获得正确视图时,onClick 会正确触发。
我想在 onClick 发生时替换图像,它会替换,但不仅限于此 ImageView。它取代了其他几个。这似乎是随机的。
onClick 的代码如下:

 public void addToCartClick(View view) {
    ImageView img = (ImageView) view;
    img.setImageResource(R.drawable.cart_add);
}  

适配器代码:

public class ShopListAdapter extends ArrayAdapter<ShopListItem> {

Context context;
int resource;
ShopListItem[] objects;

public ShopListAdapter(Context context, int resource, ShopListItem[] objects) {
    super(context, resource, objects);

    this.context = context;
    this.resource = resource;
    this.objects = objects;
}

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

    if (convertView == null) {
        // inflate the layout
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        convertView = inflater.inflate(resource, parent, false);
    }

    // object item based on the position
    ShopListItem item = objects[position];

    // get the TextView and then set the text (item name) and tag (item ID) values
    TextView itemName = (TextView) convertView.findViewById(R.id.itemName);
    itemName.setText(item.itemName);

    TextView qty = (TextView) convertView.findViewById(R.id.qty);
    qty.setText(item.quantity + "kg");

    TextView price = (TextView) convertView.findViewById(R.id.price);
    price.setText("R$" + item.price);

    TextView total = (TextView) convertView.findViewById(R.id.total);
    total.setText("R$" + item.total);

    return convertView;
}

}

我错过了什么?

【问题讨论】:

  • 发布您的适配器代码
  • 编辑以反映您的要求。
  • 问题可能在您的适配器中,您没有实现 ViewHolder 模式,这可能会返回带有错误 ID 的正确视图。请在此处发布您的适配器。
  • 试试 - img.setImageResource(null); img.setImageResource(R.drawable.cart_add);
  • 不能将 null 设置为 setImageResource。

标签: android android-layout listview onclick


【解决方案1】:

在 ShopListItem 类中取一个布尔值 -

  public boolean isSelected; 

然后签入 getView 方法并根据此布尔值设置其图像,因此当您滚动列表视图时,图像将设置为您之前选择的特定图像视图 -

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

    if (convertView == null) {
        // inflate the layout
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        convertView = inflater.inflate(resource, parent, false);
    }

    // object item based on the position
    ShopListItem item = objects[position];

    // get the TextView and then set the text (item name) and tag (item ID) values
    TextView itemName = (TextView) convertView.findViewById(R.id.itemName);
    itemName.setText(item.itemName);

    TextView qty = (TextView) convertView.findViewById(R.id.qty);
    qty.setText(item.quantity + "kg");

    TextView price = (TextView) convertView.findViewById(R.id.price);
    price.setText("R$" + item.price);

    TextView total = (TextView) convertView.findViewById(R.id.total);
    total.setText("R$" + item.total);

    ImageView img = (ImageView) view.findViewById(R.id.cartIcon);
    img.setTag(position);

    if ( objects.isSelected ){

       img.setImageResource(R.drawable.cart_add);
    }else{
        // you can set default image here
    }
  }

    return convertView;
}

并添加此代码-

 public void addToCartClick(View view) {
    object.get( Integer.parseInt(view.getTag()) ).isSelected = true;
    notifyDatasetChanged();
 }  

【讨论】:

    【解决方案2】:

    ListView 项目视图被 ListView 回收。
    您应该在 Adapter#getView 中将默认图像资源设置为 ImageView。

    已编辑 你可以使用标签。

     public void addToCartClick(View view) {
        ImageView img = (ImageView) view;
        img.setImageResource(R.drawable.cart_add);
        ((MyAdapter.MyItem)img.getTag()).addedCart = true;
    }  
    

    还有你的适配器类。

    public class MyAdapter extends BaseAdapter {
        public static class MyItem {
            public boolean addedCart;
    
            public MyItem(boolean addedCart) {
                this.addedCart = addedCart;
            }
        }
    
        public List<MyItem> itemList = new ArrayList<>();
        public MyAdapter() {
            final ArrayList<MyItem> myItems = new ArrayList<>();
            // your list size
            for (int i = 0; i < 10; i++) {
                myItems.add(new MyItem(false));
            }
            this.itemList = myItems;
        }
    
        @Override
        public int getCount() {
            return 10;
        }
    
        @Override
        public Object getItem(int position) {
            return itemList.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return 0;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Inflate View
    
            imageView.setTag(getItem(position));
            if (((MyItem)getItem(position)).addedCart){
                imageView.setImageResource(R.drawable.cart_add);
            }else{
                imageView.setImageResource(R.drawable.default_image);
            }
            return view;
        }
    }
    

    【讨论】:

    • 我不明白...我想交换图像并保持这种方式。
    • 对不起..这个答案可能是错误的..我会考虑的。
    • 在 setTag() 之后调用 notifydatasetchaged()
    【解决方案3】:

    您是否要覆盖 public boolean hasStableIds() 以返回 true?听起来正在发生的事情是您的 ListView 中的某些项目可能具有相同的 ID。如果您要覆盖 public long getItemId(int position),请确保该函数不能为不同的 ListView 项返回相同的 long。您还应该将public boolean hasStableIds() 设置为返回false

    如果这不起作用,请尝试从 XML 文件中删除 android:onClick="addToCartClick",然后在 ListAdapter 的 public View getView (int position, View convertView, ViewGroup parent) 函数中添加一个 OnClickListener,如下所示:

    imageView.setOnClickListener(new View.OnClickListener() {
        void onClick(View v) {
            addToCartClick(imageView)
        }
    });
    

    【讨论】:

      【解决方案4】:

      您应该在 getView 方法中定义您的 onClick 逻辑。您正在为它定义一个点击监听器,但它还不知道位置。从getView中可以传递item的位置来查看正确的item

      编辑:如果您要更改行本身,请关注this 链接

      【讨论】:

        【解决方案5】:

        把你所有的努力放在一起,我得出了解决方案:

        @Mohamed 建议的带有视图持有者模式的新 getView:

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
        
            ViewHolder viewHolder;
            // object item based on the position
            final ShopListItem item = objects[position];
        
            if (convertView == null) {
                // inflate the layout
                LayoutInflater inflater = ((Activity) context).getLayoutInflater();
                convertView = inflater.inflate(resource, parent, false);
        
                viewHolder = new ViewHolder();
                viewHolder.itemName = (TextView) convertView.findViewById(R.id.itemName);
                viewHolder.qty = (TextView) convertView.findViewById(R.id.qty);
                viewHolder.price = (TextView) convertView.findViewById(R.id.price);
                viewHolder.total = (TextView) convertView.findViewById(R.id.total);
                viewHolder.img = (ImageView) convertView.findViewById(R.id.cartIcon);
        
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
        
            // get the TextView and then set the text (item name) and tag (item ID) values
        
            viewHolder.itemName.setText(item.itemName);
        
            viewHolder.qty.setText(item.quantity + "kg");
        
            viewHolder.price.setText("R$" + item.price);
        
            viewHolder.total.setText("R$" + item.total);
        
            //Here's the trick
            viewHolder.img.setTag(R.string.tag_adapter, this);
            viewHolder.img.setTag(R.string.tag_item, item);
        
            if(!item.finished)
                viewHolder.img.setImageResource(R.drawable.ic_launcher);
            else
                viewHolder.img.setImageResource(R.drawable.cart_add);
            //End Here's the trick
            return convertView;
        }
        

        和onClick方法:

        public void addToCartClick(View view) {
            ShopListItem item = (ShopListItem) view.getTag(R.string.tag_item);
            ShopListAdapter adapter = (ShopListAdapter) view.getTag(R.string.tag_adapter);
        
            item.finished = !item.finished;
            adapter.notifyDataSetChanged();
        }  
        

        并且,正如@ARMV 所建议的,创建了一个“已完成”标志来检查使用了哪个图像。 这样就无需将 onClickListener 放在适配器内。并且使用适配器和当前项目设置标签我可以使用多个列表视图。
        也使用 Men Taka 建议的标签。
        它工作得很好。
        谢谢大家!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-02
          • 1970-01-01
          • 1970-01-01
          • 2016-11-28
          • 2021-09-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多