1

before the moderator take down this question as duplicate please read bellow

Ok I have tried different answers but nothing is working for me for eg I have disabled the animation which doesn't work and I'm trying to use this but I'm not using getItemID so I don't know what to do with it

Here is my Code

Home_Fragment.java // ok I have given only some part of the code that I think is required but if you want to see the entire code please tell me I will update it

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
postRecyclerView.setItemAnimator(null);
        getData();
  return view;
    }
 private void getData() {
        databaseReference.addValueEventListener(new ValueEventListener() {
            @SuppressLint("NotifyDataSetChanged")
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()) {
                    shimmerFrameLayout.stopShimmer();
                    shimmerFrameLayout.setVisibility(View.GONE);
                    postRecyclerView.setVisibility(View.VISIBLE);
                    mUploads.clear();
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        Upload upload = dataSnapshot.getValue(Upload.class);
                        assert upload != null;
                        upload.setmKey(dataSnapshot.getKey());
                        mUploads.add(upload);


                    }

                }
                postsAdapter.setUploads(mUploads);

                //notify the adapter
                postsAdapter.notifyDataSetChanged();
                loading = true;
            }


            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                loading = true;
            }
        });
    }

PostAdapter_Home.java

public class PostAdapter_Home extends RecyclerView.Adapter<PostAdapter_Home.PostViewHolder> {
    public static List<Upload> mUploads;
    public Context mcontext;

    public PostAdapter_Home(Context context, List<Upload> uploads) {
        mUploads = uploads;
        mcontext = context;
    }


    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(mcontext).inflate(R.layout.ex_home, parent, false);
        return new PostViewHolder(view);

    }

    @Override
    public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
        Shimmer shimmer = new Shimmer.ColorHighlightBuilder()
                .setBaseColor(Color.parseColor("#F3F3F3"))
                .setBaseAlpha(1)
                .setHighlightColor(Color.parseColor("#E7E7E7"))
                .setHighlightAlpha(1)
                .setDropoff(50)
                .build();
        ShimmerDrawable shimmerDrawable = new ShimmerDrawable();
        shimmerDrawable.setShimmer(shimmer);
        Upload uploadCurrent = mUploads.get(position);
        Glide.with(mcontext)
                .load(uploadCurrent.getmImageUrl())
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .placeholder(shimmerDrawable)
                .centerCrop()
                .fitCenter()
                .into(holder.imageView);

//        holder.imageView.setOnClickListener(view -> changeScaleType(holder, position));

    }


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

    public void setUploads(List<Upload> uploads){
        mUploads=uploads;
    }
    public static class PostViewHolder extends RecyclerView.ViewHolder {

        private final ShapeableImageView imageView;

        public PostViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imagePostHome);

        }


    }
}

Upload.java

package com.example.myappnotfinal.AdaptersAndMore;

import com.google.firebase.database.Exclude;

public class Upload {
    private String mImageUrl;
    private String mKey;
    private String mUserName;
    private String mComment;

    public Upload() {

    }

    public Upload(String imageUrl) {
        mImageUrl = imageUrl;
    }

    public String getmUserName() {
        return mUserName;
    }

    public void setmUserName(String mUserName) {
        this.mUserName = mUserName;
    }

    public String getmComment() {
        return mComment;
    }

    public void setmComment(String mComment) {
        this.mComment = mComment;
    }

    public String getmImageUrl() {
        return mImageUrl;
    }

    public void setmImageUrl(String mImageUrl) {
        this.mImageUrl = mImageUrl;
    }

    @Exclude
    public String getmKey() {
        return mKey;
    }

    @Exclude
    public void setmKey(String Key) {
        this.mKey = Key;
    }
}
Vasant Raval
  • 257
  • 1
  • 12
  • 31
  • hmm, I mostly use `getItemId`. It does the job. I mostly have ids in the list I want to use to populate the RecyclerView. So each element normally has a Unique ID field for me to use. – Noah Nov 11 '21 at 16:00
  • what should i do – Vasant Raval Nov 11 '21 at 16:01
  • I don't think I have seen any article online on how to fix that issue without using `getItemId`. So I suggest you find a way to make `mUploads` in your code to have a Unique ID for each of the items you add into it. – Noah Nov 11 '21 at 16:03
  • please can you tell me how can i do that or any article or resources – Vasant Raval Nov 11 '21 at 16:05
  • That medium article was the one I used myself, when I wanted to fix mine. – Noah Nov 11 '21 at 16:08
  • am guessing `mUploads` is a `List` of uploads or something, so the individual objects you add to the list should have a a unique Id field, so that you can call something like `mUploads.get(position).getId()` inside `getItemId` – Noah Nov 11 '21 at 16:11
  • yes the list contains images, and yes I have mUploads.get(position) but i don't have getItemID – Vasant Raval Nov 11 '21 at 16:30
  • I have seen some questions related to getItemId on SO like this one https://stackoverflow.com/questions/6711592/what-is-the-intent-of-the-methods-getitem-and-getitemid-in-the-android-class-bas, but I'm still confused about what should I do with it in my code – Vasant Raval Nov 11 '21 at 16:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/239124/discussion-between-noah-and-vasant-raval). – Noah Nov 11 '21 at 16:38
  • @VasantRaval use `setSupportsChangeAnimations(false)` method – IntelliJ Amiya Nov 12 '21 at 10:42
  • Are there any reasons for not using DiffUtil? I suspect that the flash is caused bu Glide trying to load items not recyclerView animations, so disabling both animations (recyclerView and Glide might help) and if you use DiffUtil, it's possible that your bind won't get called and everything work as you expect it – Amin Nov 16 '21 at 21:06

1 Answers1

0

Try ListAdapter, it manage these all animations for you. To implement this, we need write some boilerplate classes.

First, let's create the adapter.

public class YourAdapter extends ListAdapter<YourModelClass, YourAdapter.YourViewHolder> {

    public YourAdapter(@NonNull DiffUtil.ItemCallback<YourModelClass> diffCallback) {
        super(diffCallback);
    }

    public static class YourViewHolder extends RecyclerView.ViewHolder {
        
        private TextView textViewId;
        private TextView textViewName;

        private YourViewHolder(View view) {
            super(view);
            textViewId = view.findViewById(R.id.textViewId);
            textViewName = view.findViewById(R.id.textViewName);
        }

        static YourViewHolder create(ViewGroup parent) {
            return new YourViewHolder(
                    LayoutInflater.from(parent.getContext())
                            .inflate(
                                    R.layout.your_layout,
                                    parent,
                                    false
                            )
            );
        }

        void bind(YourModelClass model) {
            textViewId.setText(String.valueOf(model.getId()));
            textViewName.setText(model.getName());
        }

    }

    @NonNull
    @Override
    public YourViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return YourViewHolder.create(parent);
    }

    @Override
    public void onBindViewHolder(@NonNull YourViewHolder holder, int position) {
        holder.bind(getItem(position));
    }
}

now, let's create your class to compare list items with DiffUtill algorithm. In areItemsTheSame you need to use a unique key to compare items. In areContentsTheSame we just compare the both instances.

public class YourItemCallback extends DiffUtil.ItemCallback<YourModelClass> {

    @Override
    public boolean areItemsTheSame(@NonNull YourModelClass oldItem, @NonNull YourModelClass newItem) {
        return oldItem.getId() == newItem.getId();
    }

    @Override
    public boolean areContentsTheSame(@NonNull YourModelClass oldItem, @NonNull YourModelClass newItem) {
        return Objects.equals(oldItem, newItem);
    }
}

Finally, let's to send data to the adapter. Note that submitList method receive a list of type you specify in adapter

ListAdapter<YourModelClass, YourAdapter.YourViewHolder>

List<YourModelClass> yourList = Arrays.asList(
                new YourModelClass(1, "John"),
                new YourModelClass(1, "Mac"),
                new YourModelClass(1, "Gu"),
                new YourModelClass(1, "Gabriel")
        );

RecyclerView recyclerView = findViewById(R.id.recyclerView);
YourAdapter yourAdapter = new YourAdapter(new YourItemCallback());
recyclerView.setAdapter(yourAdapter);
yourAdapter.submitList(yourList);
gabrx
  • 73
  • 4