微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android RecyclerView 和自定义 Adapter 位置元素变化

如何解决Android RecyclerView 和自定义 Adapter 位置元素变化

我有一个填充了自定义适配器 recylerView.setAdapter(myAdapter) 的 RecylcerView,并且适配器通过 ArrayList 填充了不同的元素。在 ViewHolder 中,我覆盖了 public void onBindViewHolder(@NonNull ViewHolder viewHolder,int position) 方法。在自定义 ViewHolder 中,我放了一个按钮。该按钮上有一个单击侦听器。当我点击按钮时,我读取了变量 position 并且每次我点击同一个按钮时我都会面临变量的变化。 为什么会发生这种情况?

我的适配器是这样的:

import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.amplifyframework.core.Amplify;
import com.amplifyframework.core.model.query.Where;
import com.amplifyframework.datastore.generated.model.Comments;
import com.amplifyframework.datastore.generated.model.Likes;
import com.amplifyframework.datastore.generated.model.Posts;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.diskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.google.firebase.auth.FirebaseAuth;

import java.net.URL;
import java.util.LinkedList;

import de.hdodenhof.circleimageview.CircleImageView;

import static com.amazonaws.mobile.auth.core.internal.util.ThreadUtils.runOnUiThread;

public class PostsAdapter extends RecyclerView.Adapter<PostsAdapter.PostViewHolder>
{
    private LinkedList<Posts> usersPostsList;
    private FirebaseAuth mAuth;
    private Context context;
    //private Boolean likeChecker;
    private String currentUserId;
    private MainActivity mainActivity;
    private int currentPosition;

    public PostsAdapter(Context context,String currentUserId,MainActivity mainActivity)
    {
        this.context = context;
        this.currentUserId = currentUserId;
        this.mainActivity = mainActivity;
    }

    public PostsAdapter(LinkedList<Posts> usersPostsList,Context context)
    {
        this.usersPostsList = usersPostsList;
        this.context = context;
    }

    public void setMessages(LinkedList<Posts> usersPostsList) {
        this.usersPostsList = usersPostsList;
    }

    public static class PostViewHolder extends RecyclerView.ViewHolder
    {
        View mView;

        public static ImageButton LikePostButton,CommentPostButton;
        public TextView displayNoOfLikes,modifyPost;
        private TextView displayNoOfComments;
        String currentUserID;
        ExpandableTextView PostDescription;
        private Context context;

        public PostViewHolder(@NonNull View itemView,Context context)
        {
            super(itemView);
            mView = itemView;
            this.context = context;

            LikePostButton = (ImageButton) mView.findViewById(R.id.like_button);
            CommentPostButton = (ImageButton) mView.findViewById(R.id.comment_button);
            displayNoOfLikes = (TextView) mView.findViewById(R.id.display_no_of_likes);
            displayNoOfComments = (TextView) mView.findViewById(R.id.display_no_of_comments);
            currentUserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
            modifyPost = mView.findViewById(R.id.modify_post);
        }



        public void setLikeButtonStatus(final String PostKey) {

            Amplify.DataStore.query(
                    Likes.class,Where.matches(Likes.POST_ID.eq(PostKey.trim()).and(Likes.SENDER.eq(currentUserID.trim()))),items -> {
                        int countLikes = 0;
                        if (!items.hasNext()) {
                            LikePostButton.setimageResource(R.drawable.ic_star_border);
                        }
                        while (items.hasNext()) {
                            Likes item = items.next();
                            countLikes++;
                            LikePostButton.setimageResource(R.drawable.ic_star_fill);
                            Log.i("Amplify","Id " + item.getId());
                        }
                        int finalCountLikes = countLikes;
                        displayNoOfLikes.setText(finalCountLikes + (" Likes"));
                    },failure -> Log.e("Amplify","Could not query DataStore",failure)
            );

        }


        public void setFullname(String fullname)
        {
            TextView username = (TextView) mView.findViewById(R.id.post_user_name);
            username.setText(fullname);
        }

        public void setProfileimage(Context ctx,String profileimage)
        {
            CircleImageView image = (CircleImageView) mView.findViewById(R.id.post_profile_image);
            Amplify.Storage.getUrl(profileimage,result -> {
                        URL url = result.getUrl();
                        runOnUiThread(() -> Glide.with(ctx)
                                .load(url)
                                .apply(new RequestOptions()
                                        .diskCacheStrategy(diskCacheStrategy.NONE)
                                        .skipMemoryCache(true))
                                .into(image));
                    },error -> Log.i("Amplify","error while retrieving url"));
        }

        public void setTime(String time)
        {
            TextView PostTime = (TextView) mView.findViewById(R.id.post_time);
            PostTime.setText("   " + time);
        }
        public void setDate(String date)
        {
            TextView PostDate = (TextView) mView.findViewById(R.id.post_date);
            PostDate.setText("   " + date);
        }
        public void setDescription(String description)
        {
            PostDescription = mView.findViewById(R.id.post_description);
            PostDescription.setText(description);
        }


        public void setPostimage(Context ctx,String postimage,String id)
        {
            ImageView postimageInner = mView.findViewById(R.id.post_image);

             Amplify.Storage.getUrl(postimage,result -> {
                        URL url = result.getUrl();
                        runOnUiThread(() -> Glide.with(ctx)
                                .load(url)
                                .apply(new RequestOptions()
                                        .diskCacheStrategy(diskCacheStrategy.NONE)
                                        .skipMemoryCache(true))
                                .into(postimageInner));
                        Log.i("Amplify---------","url ok----");
                    },error -> Log.e("Amplify---------","error while retrieving url: " + error.getCause().toString()));

            postimageInner.setonClickListener(v -> {
                Intent clickPostIntent = new Intent(context,ClickPostActivity.class);
                clickPostIntent.putExtra("PostKey",id);
                clickPostIntent.putExtra("postimagePath",postimage);
                context.startActivity (clickPostIntent);
            });

        }
        public void setCountry(String country)
        {
            TextView CountryName = (TextView) mView.findViewById(R.id.post_country_name);
            CountryName.setText(country);
        }

        public void setCity(String city)
        {
            TextView City = (TextView) mView.findViewById(R.id.post_city_name);
            City.setText("- " + city);
        }


        public void setCommentStatus(final String PostKey) {

            Amplify.DataStore.query(
                    Comments.class,Where.matches(Comments.POST_ID.eq(PostKey.trim())),items -> {
                        int i = 0;
                        while (items.hasNext()) {
                            Comments comments = items.next();
                            i++;
                            int finalI = i;
                            runOnUiThread(() -> displayNoOfComments.setText(finalI + " comments"));
                            Log.i("amplify?","comment id: " + comments.getId());
                        }
                    },failure)
            );
        }
    }



    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType)
    {
        View V = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.all_posts_layout,parent,false);

        mAuth = FirebaseAuth.getInstance();
        return new PostViewHolder(V,context);

    }

    @Override
    public int getItemViewType(int position) {
        currentPosition = position;
        return position;
    }

    @Override
    public void onBindViewHolder(@NonNull PostViewHolder viewHolder,int position) {
        viewHolder.setFullname(usersPostsList.get(position).getFullname());
        viewHolder.setTime(usersPostsList.get(position).getTime());
        viewHolder.setDate(usersPostsList.get(position).getDate());
        viewHolder.setDescription(usersPostsList.get(position).getDescription());
        viewHolder.setProfileimage(context,usersPostsList.get(position).getProfileimage());
        viewHolder.setPostimage(context,usersPostsList.get(position).getPostimage(),usersPostsList.get(position).getId());
        viewHolder.setCountry(usersPostsList.get(position).getCountry());
        viewHolder.setCity(usersPostsList.get(position).getCity());


        if( viewHolder.PostDescription.originalText.length() > 100 ) {
            viewHolder.PostDescription.setonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!((ExpandableTextView)v).read) {
                        ((ExpandableTextView)v).expandText();
                        ((ExpandableTextView)v).read = true;
                    } else {
                        ((ExpandableTextView)v).truncateText();
                        ((ExpandableTextView)v).read = false;
                    }

                }
            });
        }


        viewHolder.CommentPostButton.setonClickListener(v -> {
            Intent commentsIntent = new Intent(context,CommentActivity.class);
            commentsIntent.putExtra("PostKey",usersPostsList.get(currentPosition).getId());
            context.startActivity(commentsIntent);
        });


        viewHolder.LikePostButton.setonClickListener(v -> {

            Amplify.DataStore.query(
                    Likes.class,Where.matches(Likes.POST_ID.eq(usersPostsList.get(currentPosition).getId().trim())
                            .and(Likes.SENDER.eq(currentUserId.trim()))
                            .and((Likes.RECEIVER.eq(usersPostsList.get(currentPosition).getUid())))
                    ),items -> {
                        if (items.hasNext()) {
                            Likes item = items.next();
                            Amplify.DataStore.delete(item,deleted -> Log.i("Amplify","Deleted item."),"Delete Failed.",failure)
                            );

                            Log.i("Amplify","Id " + item.getId());
                        } else {
                            Likes likes = Likes.builder()
                                    .receiver(usersPostsList.get(currentPosition).getUid().trim())
                                    .sender(currentUserId.trim())
                                    .postId(usersPostsList.get(currentPosition).getId().trim())
                                    .value("true")
                                    .build();
                            Amplify.DataStore.save(
                                    likes,success -> Log.i("Amplify","Item updated: " + success.item().getId()),error -> Log.e("Amplify","Could not save item to DataStore",error)
                            );
                        }
                    },failure -> {
                        Log.e("Amplify",failure);
                    }
            );
            notifyDataSetChanged();
        });

        viewHolder.modifyPost.setonClickListener(v -> {
            Intent intent = new Intent(context,ClickPostActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            intent.putExtra("PostKey",usersPostsList.get(currentPosition).getId());
            intent.putExtra("postimagePath",usersPostsList.get(currentPosition).getPostimage());
            context.startActivity(intent);
        });
    }


    @Override
    public int getItemCount() {
        return usersPostsList.size() ;
    }

}


似乎在单击 LikePostButton 后调用了 getItemViewType 方法,以便:viewHolder.LikePostButton.setonClickListener(v -> { 获取旧的 currentPosition 变量值

感谢所有帮助我理解的人

解决方法

您可以覆盖 getItemViewType(position:Int) 方法并替换 super 行以在 Kotlin 中仅使用这样的位置返回它:

override fun getItemViewType(position: Int): Int {
        return position
    }

在 Java 中:

@Override
public int getItemViewType(int position) {
    return position;
}
,

谢谢,我解决了它在 ViewHolder 中的按钮上设置侦听器,然后只需调用 getAbsoluteAdapterPosition() 以获得正确位置

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。