简体   繁体   中英

Custom adapter view holder positions of elements

I have a RecylcerView filled with a Custom Adapter recylerView.setAdapter(myAdapter) , and the Adapter is filled with different elements by an ArrayList .

In the ViewHolder I overrided the public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) method.

In the custom ViewHolder i put a Button. The Button has a click listener on it. When i click the Button i read the variable position and i am facing that the variable changes every time i click the same Button. Why this happens?

My Adapter is like this:

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 -> Log.e("Amplify", "Could not query DataStore", 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."),
                                    failure -> Log.e("Amplify", "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", "Could not query DataStore", 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() ;
    }

}

Seems that method getItemViewType is called after the click on LikePostButton so that: viewHolder.LikePostButton.setOnClickListener(v -> { gets an older currentPosition variable value

And also:

Does anyone knows if there is the official repository in github or somewere else of the Android RecyclerView and Adapters

Thanks to everyone helping me to understand

Try using the position passed through onBindViewHolder rather than currentposition.

viewHolder.LikePostButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "Recycle Click" + position, Toast.LENGTH_SHORT).show();
            }
    });
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
    viewHolder.LikePostButton.setOnClickListener(v -> {
        Toast.makeText(context,"Click Position "+ position,Toast.LENGTH_SHORT).show();
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM