由于回收,向下滚动时listView中的setText会不断变化

时间:2016-05-06 23:42:46

标签: android listview textview android-recyclerview

我知道在android中,listview会回收它的元素,在我的情况下,listview会在你向下滚动时回收它们。

我正在尝试制作一个让我“喜欢”帖子的Feed。

这是我的代码:

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

    final HomeFeedHolder homeFeedHolder;

    if (inflater == null)
        inflater = (LayoutInflater) activity
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.home_feed_item, null);
        homeFeedHolder = new HomeFeedHolder();
        homeFeedHolder.tvHomeFeedLike = (TextView) convertView.findViewById(R.id.tvHomeFeedLike);
        convertView.setTag(homeFeedHolder);
    } else {
        homeFeedHolder = (HomeFeedHolder) convertView.getTag();
    }

    homeFeedHolder.tvHomeFeedLike.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (homeFeedHolder.tvHomeFeedLike.getText().toString().equals("Like")) {
                HomeFeedModel homeFeedModel = (HomeFeedModel) getItem(position);
                int pid2 = item.getId();
                String pid = Integer.toString(pid2);
                HomeFeedLikePost homeFeedLikePost = new HomeFeedLikePost(position);
                homeFeedLikePost.execute(pid);
                homeFeedHolder.tvHomeFeedLike.setText("Unlike");
            }
        }
    });
}

如您所见,我在按下tvHomeFeedLike后调用setText(“不同于”)。它工作得很好但是当我向下滚动并且listview被回收时,“Like”会改变到另一个帖子。我怎样才能使它成为个人发布的?

编辑:我也在使用Volley

4 个答案:

答案 0 :(得分:0)

在项目类中添加一个布尔字段。

if (inflater == null)
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.home_feed_item, null);
        homeFeedHolder = new HomeFeedHolder();
        homeFeedHolder.tvHomeFeedLike = (TextView) convertView.findViewById(R.id.tvHomeFeedLike);

        convertView.setTag(homeFeedHolder);
    } else {
        homeFeedHolder = (HomeFeedHolder) convertView.getTag();
    }

    if(item.isLike()) homeFeedHolder.tvHomeFeedLike.setText("Unlike");
    else homeFeedHolder.tvHomeFeedLike.setText("Like");

    homeFeedHolder.tvHomeFeedLike.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {



    if(homeFeedHolder.tvHomeFeedLike.getText().toString().equals("Like")) {
                    HomeFeedModel homeFeedModel= (HomeFeedModel) getItem(position);

                        int pid2 = item.getId();
                        String pid = Integer.toString(pid2);
                        HomeFeedLikePost homeFeedLikePost = new HomeFeedLikePost(position);
                        homeFeedLikePost.execute(pid);
                        homeFeedHolder.tvHomeFeedLike.setText("Unlike");
                        item.setLike(true);
            }
        }
    });

答案 1 :(得分:0)

你的HomeFeedModel对象中的

你应该添加一个这样的参数:

 public class HomeFeedModel {

    //all your attrs

    private boolean isLiked;

    public boolean isLiked(){
        return isLiked;
    }

    public void setIsLiked(boolean liked){
        isLiked = liked;

    }
  }

然后你应该在onClick函数之外分配参数,因为它会在你滚动时占用当前位置,而不是你正在寻找的那个(这是因为回收)。 同时将对象状态更改为喜欢与否,并将text状态分配给textview,以便始终拥有对象的最新状态,而不是已回收状态。

你应该这样试试:

    final boolean isLiked = homeFeedHolder.tvHomeFeedLike.getText().toString().equals("Like");
    final HomeFeedModel homeFeedModel= (HomeFeedModel) getItem(position);
    final int pid2 = item.getId();
    final String pid = Integer.toString(pid2);
    final HomeFeedLikePost homeFeedLikePost = new HomeFeedLikePost(position);

    homeFeedHolder.tvHomeFeedLike.setText(homeFeedModel.isLiked() ? "UnLike" : "Like"); 
   homeFeedHolder.tvHomeFeedLike.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {

            if(isLiked) {
                homeFeedLikePost.execute(pid);
                homeFeedModel.setIsLiked(false);
                homeFeedHolder.tvHomeFeedLike.setText("Unlike");
                notifyDataSetChanged();
            }
        }
    });

答案 2 :(得分:0)

当您按某个项目的喜欢和setText("Unlike")时,您必须保持该状态。

首先,您必须了解getView()的工作原理。当您滚动到其位置时,getView方法基本上可以帮助您加载项目。要显示的视图取决于您。特别是,您可以定义应显示的UI元素(文本,图像,按钮等)。一些UI元素依赖于状态。

在您的情况下,TextView显示"与"不同当帖子被喜欢时,反之亦然。 TextView与状态有关。因此,你必须记住"您的帖子状态在某处..通过保存状态,下次滚动到该项时,您的getView方法可以决定要显示的文字:

HomeFeedModel homeFeedModel= (HomeFeedModel) getItem(position);
int pid2 = item.getId();
HomeFeedLikePost homeFeedLikePost = new HomeFeedLikePost(position);
boolean isLiked = homeFeedLikePost.isLiked();
if (isLiked) {
     homeFeedHolder.tvHomeFeedLike.setText("Unlike");   
} else {
     homeFeedHolder.tvHomeFeedLike.setText("Like");
}

在上面的示例中,isLikedHomeFeedLikePost中的属性之一。这意味着,当您Like发布帖子时,您也应该在数据库中更新此属性(在onClickListener内执行此操作)。

希望这对你有用。

答案 3 :(得分:0)

您可以将喜欢的项目ID添加到适配器:

Set<Integer> likedItems = new HashSet<>();

在getView中:

    int pid = (HomeFeedModel) getItem(position);
    if (likedItems.contains(pid))
        homeFeedHolder.tvHomeFeedLike.setText("Unlike");
    else
        homeFeedHolder.tvHomeFeedLike.setText("Like");

在onClick上:

    if (likedItems.contains(pid)){
        likedItems.remove(pid);
    }
    else{
        likedItems.add(pid);
    }
    if (likedItems.contains(pid))
        homeFeedHolder.tvHomeFeedLike.setText("Unlike");
    else
        homeFeedHolder.tvHomeFeedLike.setText("Like");