【问题标题】:Android Imageview in Listview onClick change image doesn't work properlyListview onClick更改图像中的Android Imageview无法正常工作
【发布时间】:2014-08-20 11:14:47
【问题描述】:

我有一个 ListView 并且在每个 ListviewItem 中都有一个带有小星星的 ImageView(用于将其标记为收藏)。因此,我在自定义 ArrayAdapter 中的每个项目上都将 OnClickListener 放入 ImageView。

imgStar.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Bitmap bitmap = ((BitmapDrawable)imgStar.getDrawable()).getBitmap();
            Bitmap bitmap2 = ((BitmapDrawable)(context.getResources().getDrawable(R.drawable.ic_action_not_important))).getBitmap();

            if(bitmap != bitmap2) {
                    imgStar.setImageResource(R.drawable.ic_action_not_important);
            } else {
                    imgStar.setImageResource(R.drawable.ic_action_important);
            }
        }
    });

问题:当我得到一些项目并单击例如第一个项目的星号时,图像会发生应有的变化,但是一些项目降低了图像也会发生变化o.O 我用一些代码对其进行了测试:我不会想到的是它只是更改图像(在下面的另一个项目上),将在 onclick 中执行的代码仅针对我真正单击的项目而不是执行对于图像也发生变化的那个。

为什么列表中随机其他项目的图像也会改变?我希望有人可以帮助我。

自定义适配器构造代码

public LinkArrayAdapter(Context con, int textViewResourceId) {
    super(con, textViewResourceId);
    context = con;

}

【问题讨论】:

  • 这段代码是否在自定义适配器中?
  • 是的,此代码在添加到列表视图的自定义适配器中(在 getView 事件中)
  • 您需要一个随机变化的图像,同时单击星形图像。对吧?
  • 您需要将点击位置的位置存储在数组中并检查项目位置是否在数组内。
  • 不,这完全不是我想要的:D 我只想在我真正点击的图像视图中更改图像,而不是在我从未点击过的项目的图像视图中更改图像

标签: java android android-listview imageview android-arrayadapter


【解决方案1】:

主要问题是您无法更改onClick 中项目的图像然后离开它并希望它会在列表中的每个项目上更新。因为onClick 的调用时间与getView 不同。因此,您必须在onClick 之外设置项目图像,但在getView 中设置,因此每次getView 调用特定项目时,它都会为该项目设置适当的图像。

在您的 CustomAdapter 类中定义一个布尔数组:

private boolean[] stars;

然后在你的类的构造方法中,将其初始化为:

this.stars = new boolean[items.size()];

onClick 方法中:

// **Edited to apply image update at click**
stars[position] = !stars[position];
notifyDataSetInvalidated();

最后在自定义适配器的getView()方法中 (确保此代码不在任何其他内部块中):

if (stars[position])
  imgStar.setImageResource(R.drawable.ic_action_important);
else
  imgStar.setImageResource(R.drawable.ic_action_not_important);

【讨论】:

  • 在构造函数中我没有items变量
  • 那么您传递给适配器以显示什么类型的数据以及适配器类中的变量名称是什么?
  • 我通过“OneComment”类传递它,数据是不同的字符串。在 OneComment 构造函数中,我将其设置为this.link = link,在我的适配器中我调用OneComment comment = getItem(position),然后我可以使用comment.link 之类的数据作为链接,例如
  • 请在您的问题中添加您的自定义适配器构造函数代码
  • 抱歉,我猜不出你的数据数组在哪里。但它必须是数组或 ArrayList,因为您有一个列表视图,因此您有一个数据列表并且它具有指定的大小。您必须将“stars”布尔数组大小设置为该大小。
【解决方案2】:
    private int  selectedPositions ;

    // /... your code.
            convertView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    OneComment mComment = mlist.get(position);
                    mComment.isStart = !mComment.isStart;
                    if(mComment.isStar){
//set star image
} else{
do not set star image}

                }
            });

【讨论】:

  • 我点击第一个项目的星号,它被添加了,但是在第 7 个项目上它也被添加了,和以前一样的问题:/
  • 你只想要一个从整个列表开始的项目吗?
  • 确切地说,带有星标的项目应该与我点击该星标的图像视图的项目完全相同(我认为它几乎类似于将电子邮件标记为收藏的 gmail 应用程序)
  • 对不起,这仍然不起作用。它总是设置我从未点击过的另一颗星 :( 编辑:现在有一个可行的解决方案(见上文),但仍然为你的想法和帮助投了赞成票!:) 谢谢
【解决方案3】:

@semsamot 的回答有效,但是 notifyDataSetInvalidated() 导致列表重新加载并转到第一项。 请改用notifyDataSetChanged()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多