android RecyclerView getAdapterPosition()在回调时返回-1,因此无法显示项目的新外观

7gs2gvoe  于 2023-02-20  发布在  Android
关注(0)|答案(2)|浏览(378)

我的RecyclerView上的每个项目都有一个按钮,该按钮具有三种状态:打开、加载和关闭。
初始时所有按钮都处于OPEN状态,当点击按钮时,按钮状态变为LOADING,并在后台进行网络调用,网络调用成功后,按钮状态应变为CLOSED。
因此,在我的适配器中,我使用了以下代码:

holder.button.setOnClickListener(v -> {
    holder.state = LOADING;
    notifyItemChanged(holder.getAdapterPosition()); /* 1 */
    callNetwork(..., () -> {
        /* this is the callback that runs on the main thread */
        holder.state = CLOSED;
        notifyItemChanged(holder.getAdapterPosition()); /* 2 */
    });
});

LOADING状态始终在/* 1 */处正确可视化,因为getAdapterPosition()为我提供了正确的位置。
但是,按钮的CLOSED状态永远不会可视化,因为getAdapterPosition/* 2 */处始终返回-1
在这种情况下,我可能会错误地理解getAdapterPosition()

如何在回调时刷新项目的外观?

r7knjye2

r7knjye21#

来自文档:
请注意,如果调用了notifyDataSetChanged(),则在下一次布局传递之前,此方法的返回值将为NO_POSITION
NO_POSITION是一个常量,其值为-1。这可能解释了为什么您在这里得到的返回值为-1。
在任何情况下,为什么不找到模型在底层数据集中的位置,然后调用notifyItemChanged(int position)呢?您可以将模型作为字段保存在holder中。
例如:

public class MyHolder extends RecyclerView.ViewHolder {
    
    private Model mMyModel;

    public MyHolder(Model myModel) {
        mMyModel = myModel;
    }
    
    public Model getMyModel() {
        return mMyModel;
    }
}

holder.button.setOnClickListener(v -> {
    holder.state = LOADING;
    notifyItemChanged(holder.getAdapterPosition());
    callNetwork(..., () -> {
        /* this is the callback that runs on the main thread */
        holder.state = CLOSED;
        int position = myList.indexOf(holder.getMyModel());
        notifyItemChanged(position);
    });
});

或者,如果位置为-1,则可以忽略,如下所示:

holder.button.setOnClickListener(v -> {
    holder.state = LOADING;
    int preNetworkCallPosition = holder.getAdapterPosition();
    if (preNetworkCallPosition != RecyclerView.NO_POSITION) {
        notifyItemChanged(preNetworkCallPosition);
    }
    callNetwork(..., () -> {
        /* this is the callback that runs on the main thread */
        holder.state = CLOSED;
        int postNetworkCallPosition = holder.getAdapterPosition();
        if (postNetworkCallPosition != RecyclerView.NO_POSITION) {
             notifyItemChanged(postNetworkCallPosition);
        }
    });
});
4c8rllxm

4c8rllxm2#

获取适配器位置();当RecyclerView进行布局计算时,它总是返回-1。您在ViewHolder内部调用此方法。这意味着RecyclerView正在进行计算。
如果您需要在视图的单击操作中定位,请在public void onClick(final View v)方法中调用它,例如:
“@覆盖BindViewHolder上的公共void(@NonNull最终ViewHolder占位符,最终整数位置){

final Students user = mUsers.get(position);
    holder.Name.setText(user.getFullname());
    holder.Index.setText(user.getIndex_number());

    if (user.getThumbnail().equals("default")) {
        holder.profile_image.setImageResource(R.drawable.profile_pic);
    } else {
        Picasso.get().load(user.getThumbnail())
                .placeholder(R.drawable.profile_pic)
                .into(holder.profile_image);
    }

  holder.itemView.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(final View v) {
           **list_user_id = mUsers.get(position).getId();**

           Intent Sub = new Intent(mContext, UserProfileActivity.class);
           Sub.putExtra("user_id1", list_user_id);
           mContext.startActivity(Sub);

但不是

获取适配器位置();当RecyclerView进行布局计算时,它总是返回-1。您在ViewHolder内部调用此方法。这意味着RecyclerView正在进行计算。
如果您需要在视图的单击操作中定位,请在public void onClick(final View v)方法中调用它,例如:
@覆盖BindViewHolder上的公共void(@NonNull最终ViewHolder持有者,最终整数位置){

final Students user = mUsers.get(position);
    holder.Name.setText(user.getFullname());
    holder.Index.setText(user.getIndex_number());

**list_user_id = mUsers.get(position).getId();**


    if (user.getThumbnail().equals("default")) {
        holder.profile_image.setImageResource(R.drawable.profile_pic);
    } else {
        Picasso.get().load(user.getThumbnail())
                .placeholder(R.drawable.profile_pic)
                .into(holder.profile_image);
    }

  holder.itemView.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(final View v) {

           Intent Sub = new Intent(mContext, UserProfileActivity.class);
           Sub.putExtra("user_id1", list_user_id);
           mContext.startActivity(Sub);

相关问题