Search code examples
androidandroid-recyclerviewandroid-viewpager

Why these random marks are appearing in every recyclerview and viewpager items?


I have 2 recycler views and a view pager in a fragment. Everything else works fine but both recycler view items are showing a random mark on the upper left corner of every items. And same thing is happening for the view pager items.

This fragment is in a fragment activity and view pager is using pager adapter. And I am using Picasso library to load images on the items and also using network policy to cache the images in disk.

recycler view items appearing like this

view pager items appearing like this

Recycler View adapter

public class CourseListAdapter extends RecyclerView.Adapter<CourseListAdapter.CourseListViewHolder> {

    public static final int HOME_PAGE = 1;
    public static final int DISPLAY_COURSE = 2;

    private Picasso mPicasso;

    private List<DisplayCourse> courseList;

    private static final String TAG = "CourseListAdapter";

    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onItemClick(int position, View view);
    }

    private String mSender;

    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }

    public CourseListAdapter(List<DisplayCourse> courseList, String sender) {
        this.courseList = courseList;
        this.mSender = sender;
        mPicasso = Picasso.get();
    }

    @NonNull
    @Override
    public CourseListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());

        switch (viewType) {
            case 1:
                View view1 = inflater.inflate(R.layout.recom_course_home_layout, parent, false);
                return new CourseListViewHolder(view1, mListener);
            case 2:
                View view2 = inflater.inflate(R.layout.display_course_layout, parent, false);
                return new CourseListViewHolder(view2, mListener);

            default:
                View view3 = inflater.inflate(R.layout.section_video_item_layout, parent, false);
                return new CourseListViewHolder(view3, mListener);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull CourseListViewHolder holder, int position) {

        holder.title.setText(courseList.get(position).getCourseTitle());

        mPicasso.load(courseList.get(position).getThumbnailURL())
                .networkPolicy(NetworkPolicy.OFFLINE)
                .into(holder.thumbnail, new Callback() {
                    @Override
                    public void onSuccess() {

                    }

                    @Override
                    public void onError(Exception e) {
                        mPicasso.load(courseList.get(position).getThumbnailURL())
                                .error(R.drawable.ofklogo)
                                .into(holder.thumbnail, new Callback() {
                                    @Override
                                    public void onSuccess() {

                                    }

                                    @Override
                                    public void onError(Exception e) {

                                    }
                                });
                    }
                });
    }

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

    public static class CourseListViewHolder extends RecyclerView.ViewHolder {

        ImageView thumbnail;
        TextView title;

        public CourseListViewHolder(@NonNull View itemView, final OnItemClickListener listener) {
            super(itemView);

            title = itemView.findViewById(R.id.courseTitle);
            thumbnail = itemView.findViewById(R.id.courseThumbNailImageView);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                    if (listener != null) {
                        if (position != RecyclerView.NO_POSITION) {
                            listener.onItemClick(position, view);
                        }
                    }
                }
            });
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (mSender.equals("home_page")) {
            return HOME_PAGE;
        } else if (mSender.equals("displayCourse")) {
            return DISPLAY_COURSE;
        }
        return -1;
    }
}

View pager adapter

public class VideoSliderAdapter extends PagerAdapter {

    private boolean doNotifyDataSetChangedOnce = false;

    private static final String TAG = "VideoSliderAdapter";

    private YouTubePlayerView youTubePlayerView;
    private View gradientView;
    private ImageView thumbNail;
    private LinearLayout layout;

    private Picasso picasso;

    private List<Video> videoList;
    private Context mContext;

    private Lifecycle mLifeCycle;

    public VideoSliderAdapter(List<Video> videoList, Context context, Lifecycle lifecycle) {
        this.videoList = videoList;
        this.mContext = context;
        this.mLifeCycle = lifecycle;
        doNotifyDataSetChangedOnce = true;
        picasso = Picasso.get();
    }

    @Override
    public int getCount() {

        if (doNotifyDataSetChangedOnce) {
            doNotifyDataSetChangedOnce = false;
            notifyDataSetChanged();
        }

        return videoList.size();
    }

    @Override
    public int getItemPosition(@NonNull Object object) {
        return POSITION_NONE;
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return (view == (CardView) object);
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {

        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = inflater.inflate(R.layout.video_paly_layout, container, false);

        TextView title = view.findViewById(R.id.videoTitle);
        title.setText(videoList.get(position).getVideoTitle());

        gradientView = view.findViewById(R.id.gradientView);

        thumbNail = view.findViewById(R.id.videoThumbNail);

        picasso.load(videoList.get(position).getVideoThumbNail())
                .networkPolicy(NetworkPolicy.OFFLINE)
                .into(thumbNail, new Callback() {
                    @Override
                    public void onSuccess() {

                    }

                    @Override
                    public void onError(Exception e) {
                        picasso.load(videoList.get(position).getVideoThumbNail())
                                .error(R.drawable.ofklogo)
                                .into(thumbNail, new Callback() {
                                    @Override
                                    public void onSuccess() {

                                    }

                                    @Override
                                    public void onError(Exception e) {

                                    }
                                });
                    }
                });

        layout = view.findViewById(R.id.videoPlayLayout);

        youTubePlayerView = view.findViewById(R.id.youtube_player_view);

        mLifeCycle.addObserver(youTubePlayerView);

        new AddListener(youTubePlayerView, position).execute();

        container.addView(view);

        return view;

    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((CardView) object);
    }

Recycler view holder layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="150dp"
    android:layout_height="200dp"
    android:layout_marginStart="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?android:attr/selectableItemBackground"
    app:cardCornerRadius="8dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/courseThumbNailImageView"
            android:layout_width="match_parent"
            android:layout_height="130dp"
            android:layout_alignParentTop="true"
            android:scaleType="fitXY"
            android:src="@drawable/art_thumb" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/courseThumbNailImageView">

            <TextView
                android:id="@+id/courseTitle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:maxLines="2"
                android:text="Course title"
                android:textAlignment="center"
                android:textColor="@android:color/black"
                android:textStyle="bold" />

        </RelativeLayout>

    </RelativeLayout>

</androidx.cardview.widget.CardView>

view pager layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    app:cardCornerRadius="8dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
            android:id="@+id/youtube_player_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:autoPlay="false" />

        <ImageView
            android:id="@+id/videoThumbNail"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY" />

        <View
            android:id="@+id/gradientView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/gradient_drawable" />

        <LinearLayout
            android:id="@+id/videoPlayLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="?attr/selectableItemBackground"
            android:clickable="true"
            android:focusable="true"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="16dp">

            <ImageView
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:padding="8dp"
                android:src="@drawable/play_button" />

            <TextView
                android:id="@+id/videoTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:maxLines="2"
                android:text="Course title"
                android:textColor="@android:color/white"
                android:textStyle="bold" />


        </LinearLayout>

    </RelativeLayout>

</androidx.cardview.widget.CardView>

Solution

  • When loading image using Picasso use: setIndicatorsEnabled(false)

    picasso.load(videoList.get(position).getVideoThumbNail())
         .networkPolicy(NetworkPolicy.OFFLINE)
         .setIndicatorsEnabled(false)
         .into(...);
    

    The colors indicate this:

    • Green: Image is fetched from memory
    • Blue: Image is fetched from disk
    • Red: Image is fetched from network