欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Listview点赞问题关于图片重复问题

程序员文章站 2024-03-31 16:48:58
《最近做一个小功能遇到这么一个问题,listview 与 baseadapter结合使用,关于点赞的的时候 图片重复问题,比如:我在第1个item 点赞然后 心型换成了红色...

《最近做一个小功能遇到这么一个问题,listview 与 baseadapter结合使用,关于点赞的的时候 图片重复问题,比如:我在第1个item 点赞然后 心型换成了红色,但是以后每隔几个item就会出现一个红色的心,响应事件是对的,不知道哪出的问题,请大神解答”》

上面是一小哥在论坛中发的帖子遇到的问题,跟我遇到的问题一样,下面有很多热心的评论哥们给出了思路,我一想,原来这么简单啊。

先给出实现代码,最后再来讲思路好了。

这篇博客我重新编辑了一次,加上了动画和收藏的效果,评论的哥们说收藏和点赞不能同时进行,图片会错乱,我给了他思路,他还是没实现,哎,我还是再来一遍,修改修改吧,博主真是关心大家啊

效果图

Android Listview点赞问题关于图片重复问题

mainactivity.java

public class mainactivity extends activity {
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    //模拟的数据内容集合
    list<contentbean> data = new arraylist<contentbean>();
    for (int i = 0; i < 15; i++) {
      contentbean bean = new contentbean();
      // 默认都给他们赋值当前都没有点赞
      bean.setzanfocus(false);
      bean.setzannum(i);
      // 默认都给他们赋值当前都没有收藏
      bean.setshoucanfocus(false);
      bean.setshoucannum(i);
      data.add(bean);
    }
    listview listview = (listview) findviewbyid(r.id.listview);
    listview.setadapter(new myadapter(this,data));
  }
main.xml
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.example.zan.mainactivity" >
  <listview
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
  </listview>
</relativelayout>
contentbean.java
public class contentbean {
  private boolean zanfocus, shoucanfocus;
  private int zannum, shoucannum;
  public boolean isshoucanfocus() {
    return shoucanfocus;
  }
  public void setshoucanfocus(boolean shoucanfocus) {
    this.shoucanfocus = shoucanfocus;
  }
  public int getshoucannum() {
    return shoucannum;
  }
  public void setshoucannum(int shoucannum) {
    this.shoucannum = shoucannum;
  }
  public boolean iszanfocus() {
    return zanfocus;
  }
  public void setzanfocus(boolean zanfocus) {
    this.zanfocus = zanfocus;
  }
  public int getzannum() {
    return zannum;
  }
  public void setzannum(int zannum) {
    this.zannum = zannum;
  }
}
myadapter.java
public class myadapter extends baseadapter {
  list<contentbean> data = new arraylist<contentbean>();
  context context;
  public myadapter(context context, list<contentbean> data) {
    this.context = context;
    this.data = data;
  }
  @override
  public int getcount() {
    return data.size();// 返回20条数据
  }
  @override
  public object getitem(int arg0) {
    return data.get(arg0);
  }
  @override
  public long getitemid(int position) {
    // todo auto-generated method stub
    return position;
  }
  @override
  public view getview(final int position, view convertview, viewgroup parent) {
      final viewholder holder;
    final contentbean bean = data.get(position);
    if (convertview == null) {
      convertview = layoutinflater.from(context).inflate(r.layout.item,
          parent, false);
      holder = new viewholder();
      holder.zan_img = (imageview) convertview.findviewbyid(r.id.zan_img);
      holder.zan_num = (textview) convertview.findviewbyid(r.id.zan_num);
      holder.shoucan_img = (imageview) convertview.findviewbyid(r.id.shoucan_img);
      holder.shoucan_num = (textview) convertview.findviewbyid(r.id.shoucan_num);
      convertview.settag(holder);
    } else {
      holder = (viewholder) convertview.gettag();
    }
    // 取出bean中当记录状态是否为true,是的话则给img设置focus点赞图片
    if (bean.iszanfocus()) {
      holder.zan_img.setimageresource(r.drawable.zan_focus);
    } else {
      holder.zan_img.setimageresource(r.drawable.zan_release);
    }
    // 取出bean中当记录状态是否为true,是的话则给img设置release收藏图片
    if (bean.isshoucanfocus()) {
      holder.shoucan_img.setimageresource(r.drawable.shoucang_focus);
    } else {
      holder.shoucan_img.setimageresource(r.drawable.shoucang_release);
    }
    // 设置赞的数量
    holder.zan_num.settext(bean.getzannum() + "");
    //设置收藏的数量
    holder.shoucan_num.settext(bean.getshoucannum()+"");
    holder.zan_img.setonclicklistener(new onclicklistener() {
      @override
      public void onclick(view v) {
        // 获取上次是否已经被点击
        boolean flag = bean.iszanfocus();
        // 判断当前flag是点赞还是取消赞,是的话就给bean值减1,否则就加1
        if (flag) {
          bean.setzannum(bean.getzannum() - 1);
        } else {
          bean.setzannum(bean.getzannum() + 1);
        }
        // 反向存储记录,实现取消点赞功能
        bean.setzanfocus(!flag);
        animationtools.scale(holder.zan_img);
      }
    });
    holder.shoucan_img.setonclicklistener(new onclicklistener() {
      @override
      public void onclick(view v) {
        // 获取上次是否已经被点击
        boolean flag = bean.isshoucanfocus();
        // 判断当前flag是收藏还是取收藏,是的话就给bean值减1,否则就加1
        if (flag) {
          bean.setshoucannum(bean.getshoucannum() - 1);
        } else {
          bean.setshoucannum(bean.getshoucannum() + 1);
        }
        // 反向存储记录,实现取消收藏功能
        bean.setshoucanfocus(!flag);
        //动画
        animationtools.scale(holder.shoucan_img);
      }
    });
    return convertview;
  }
  private class viewholder {
    private imageview zan_img,shoucan_img;
    private textview zan_num,shoucan_num;
  }
}
item.xml
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="50dp"
  android:gravity="center"
  android:orientation="horizontal" >
  <imageview
    android:id="@+id/zan_img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
   />
  <textview
    android:id="@+id/zan_num"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />
</linearlayout>
animationtools.java
public class animationtools {
  public static void scale(view v) {
    scaleanimation anim = new scaleanimation(1.0f, 1.5f, 1.0f, 1.5f,
        animation.relative_to_self, 0.5f, animation.relative_to_self,
        0.5f);
    anim.setduration(300);
    v.startanimation(anim);
  }
}

代码其实很简单,稍作理解还是很容易弄懂的,我们在listview更新item中的数据的时候,一定要明白一个道理,不要在item的view中直接更改数据(刚开始做的时候我就是直接holder.zan_img.setimageresource(资源图片),发现往下滑动的时候,上一次的触摸记录被下面的item给复用了,造成了数据的混乱),不然会造成数据的混乱,要是明白的listview的工作原理的话,可能会更清楚的明白,listview每次加载的数据是当前屏幕的一屏数据(其实我了解的不多,但是在打印log的时候,发现log出来初始化的数据就是一屏的数据),当你如果直接去改变view的样式的话,你触摸的当前item会被下面还未出现的item给复用掉,我是这样理解的=-=。