2021年4月25日星期日

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

https://stackoverflow.com/questions/67258488/custom-adapter-view-holder-positions-of-elements April 26, 2021 at 05:32AM

没有评论:

发表评论