如何立即更新ListView中的列表项?

时间:2016-08-28 20:58:30

标签: java android listview parse-platform listadapter

我想做的就是增加"喜欢"我的Feed中的Comment对象的值,并通知适配器该项已更改。预期的行为应如下:1)用户喜欢评论,2)ListView更新与评论的新值。设置this.adapter.add(mComments.get(position - 1));将替换为之前的评论。使用this.adapter.add(mComments.get(position)会崩溃该应用。有没有办法做到这一点?我想,因为它已被删除,你无法将其添加回来......除了升级到RecyclerAdapter并调用notifyItemChanged(int position)之外,还有其他选择吗?

public class CommentAdapter extends ArrayAdapter<ParseObject> {

    protected Context mContext;
    protected List<ParseObject> mComments;
    private CommentAdapter adapter;

    ImageLoader profilePictureImageLoader;

    public CommentAdapter(Context context, List<ParseObject> comments) {
        super(context, R.layout.comment_listview_item, comments);
        mContext = context;
        mComments= comments;
        this.adapter = this;

        profilePictureImageLoader = new ImageLoader(new ProfilePictureFileCache(mContext));
    }

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

holder.likeImage.setOnClickListener(v -> {
    v.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.image_click));
    createLike(position);
});

    return convertView;
}

功能如下:

private void createLike(int position) {

        ParseQuery<ParseObject> query = new ParseQuery<>(ParseConstants.CLASS_COMMENT);
        query.whereEqualTo(ParseConstants.KEY_OBJECT_ID, getItem(position).getObjectId());
        query.findInBackground((comment, e) -> {
            // Find the single Comment object associated with the current ListAdapter position
            if (e == null) for (ParseObject commentObject : comment) {

                // Create a list to store the likers of this Comment
                List<String> likedBy = commentObject.getList("likedBy");
                System.out.println(likedBy);

                // If you are not on that list, then create a Like
                if (!(likedBy.contains(ParseUser.getCurrentUser().getObjectId()))) {

                    // Create new Like object
                    ParseObject newLike2 = new ParseObject(ParseConstants.CLASS_LIKE);
                    newLike2.put(ParseConstants.KEY_SENDER_ID, ParseUser.getCurrentUser());
                    newLike2.put(ParseConstants.KEY_COMMENT_OBJECT_ID, commentObject);
                    Toast.makeText(getContext(), "Comment liked", Toast.LENGTH_SHORT).show();
                    newLike2.saveInBackground();

                    // Add unique User objectId to likedBy array in Parse
                    commentObject.addAllUnique("likedBy", Collections.singletonList(ParseUser.getCurrentUser().getObjectId()));
                    commentObject.saveInBackground();

                    // Increment the likeCount in the Comment feed
                    incrementLikeCount(commentObject, position);

                    // Initiate Like notification
                    handleLikeNotification(query, commentObject);

                } else {
                    Toast.makeText(getContext(), "You already liked this Comment", Toast.LENGTH_SHORT).show();
                }

            }
            else {
                Log.e("Error", e.getMessage());
            }
        });

    }

private void incrementLikeCount(ParseObject commentObject, int position); 

    // Increment likeCount on related Comment object
    commentObject.increment("likeCount");
    commentObject.saveInBackground();

    this.adapter.remove(mComments.get(position));
    this.adapter.add(mComments.get(position));
    this.adapter.notifyDataSetChanged();

    }

我得到以下异常:

08-28 22:46:04.359 28894-28894/com.yitter.android E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.yitter.android, PID: 28894
    java.lang.IndexOutOfBoundsException: Invalid index 3, size is 2
        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
        at java.util.ArrayList.get(ArrayList.java:308)
        at com.yitter.comment.CommentAdapter.lambda$incrementLikeCount$33(CommentAdapter.java:260)
        at com.yitter.comment.CommentAdapter.access$lambda$6(CommentAdapter.java:0)
        at com.yitter.comment.CommentAdapter$$Lambda$9.done(Unknown Source)
        at com.parse.ParseTaskUtils$2$1.run(ParseTaskUtils.java:116)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

3 个答案:

答案 0 :(得分:1)

好的,我知道如何解决你的问题。

这是你的代码:

private void incrementLikeCount(ParseObject commentObject, int position); 

    // Increment likeCount on related Comment object
    commentObject.increment("likeCount");
    commentObject.saveInBackground();

    this.adapter.remove(mComments.get(position));
    this.adapter.add(mComments.get(position));
    this.adapter.notifyDataSetChanged();

}

看,如果列表大小等于4,并且您调用incrementLikeCount,其值position等于3(列表的最后一个元素),则应用程序将崩溃。你首先删除列表中的一个对象(所以它的大小现在是3(并且它的最后一个索引位置等于2),并且在你尝试从列表中检索相同的元素后传递相同的position值(=3)。只要最后一个索引现在等于2,并且您尝试获取索引3中的元素,应用程序就会崩溃。

考虑将代码更改为:

private void incrementLikeCount(ParseObject commentObject, int position); 

    // Increment likeCount on related Comment object
    commentObject.increment("likeCount");
    commentObject.saveInBackground();

    this.adapter.remove(commentObject);
    this.adapter.add(commentObject);
    this.adapter.notifyDataSetChanged();

}

但是看,你正在删除并添加相同的对象到列表!你可以只更新对象并调用this.adapter.notifyDataSetChanged();

private void incrementLikeCount(ParseObject commentObject, int position); 

    // Increment likeCount on related Comment object
    commentObject.increment("likeCount");
    commentObject.saveInBackground();

    this.adapter.notifyDataSetChanged();

}

答案 1 :(得分:1)

您根本不需要添加/删除视图。

您应该更新您的模型(如果您为我假设的每一行都有一个注释对象,并且使用“like”计数),则调用notifydatasetchanged()。

此外,您应该更新为使用RecycleView,这是他们创建它的原因之一,因此您只需对一个项目而不是所有项目调用notifyitemchanged()。

答案 2 :(得分:0)

试试这个:

private void incrementLikeCount(ParseObject commentObject, int position); 
    commentObject.increment("likeCount");
    mComments.get(position).increment("likeCount");
    this.adapter.notifyDataSetChanged();      
    commentObject.saveInBackground();
}

或者,如果commentObject有更多更改,则增加likeCount,您可以执行此操作:

private void incrementLikeCount(ParseObject commentObject, int position); 
    commentObject.increment("likeCount");
    this.adapter.remove(position);
    this.adapter.add(commentObject);
    this.adapter.notifyDataSetChanged();      
    commentObject.saveInBackground();
}