Search code examples
androidandroid-studioandroid-recyclerviewimageviewandroid-videoview

setOnClickListener picking up wrong image to next activity in onBindViewHolder


I am trying to show image in new activity from onBindViewHolder. But it is picking up wrong image and setting in ImageView and sometimes same image showing while clicking all the images. I am not sure because of loading list of files inside RecyclerView may cause this. Any point of improvement will be helpful.

GalleryFragment.java

package com.example.mokkajokes.ui.whatsappstatus;



public class GalleryFragment extends Fragment {

private static final String WHATSAPP_STATUSES_LOCATION = "/WhatsApp/Media/.Statuses";
private RecyclerView mRecyclerViewMediaList;
private TextView message;
private LinearLayoutManager mLinearLayoutManager;
public static final String TAG = "Home";

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.fragment_ws, container, false);
    ((AppCompatActivity)getActivity()).getSupportActionBar().setIcon(R.mipmap.ic_launcher);
    ((AppCompatActivity)getActivity()).getSupportActionBar().setHomeButtonEnabled(true);
    ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);

    mRecyclerViewMediaList = (RecyclerView) root.findViewById(R.id.recyclerViewMedia);
    message = (TextView) root.findViewById(R.id.message);
    RecyclerView.LayoutManager manager = new GridLayoutManager(getActivity(), 2);
    mRecyclerViewMediaList.setLayoutManager(manager);
    //RecyclerViewMediaAdapter recyclerViewMediaAdapter = new RecyclerViewMediaAdapter(this.getListFiles(new File(Environment.getExternalStorageDirectory().getAbsolutePath().toString()+WHATSAPP_STATUSES_LOCATION)), getActivity());
    WSAdapter recyclerViewMediaAdapter = new WSAdapter(this.getListFiles(new File("/storage/extSdCard/"+WHATSAPP_STATUSES_LOCATION)), getActivity());
    mRecyclerViewMediaList.setAdapter(recyclerViewMediaAdapter);
    recyclerViewMediaAdapter.notifyDataSetChanged();
    return root;
}

private ArrayList<File> getListFiles(File parentDir)
{
    Toast.makeText(getActivity(), "Ext Dir " + parentDir, Toast.LENGTH_SHORT).show();
    ArrayList<File> inFiles = new ArrayList<>();
    File[] files;

    files=parentDir.listFiles();

    if(files!=null)
    {
        for(File file:files)
        {
            if(file.getName().endsWith(".jpg") || file.getName().endsWith(".gif") || file.getName().endsWith(".mp4"))
            {
                if(!inFiles.contains(file))
                    inFiles.add(file);
            }
        }
    }
    if(inFiles.size()>0)
        message.setVisibility(View.GONE);
    return inFiles;
}
}

WSAdapter.java

package com.example.mokkajokes.ui.whatsappstatus;

public class WSAdapter extends 
RecyclerView.Adapter<WSAdapter.ImageViewHolder> {
private Context mContext;
private ArrayList<File> filesList;
File uploadCurrent;

public WSAdapter(ArrayList<File> uploads,Context context) {
    this.filesList = uploads;
    this.mContext =  context;
}
@Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View inflatedView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.ws_image_item, parent, false);
    return new ImageViewHolder(inflatedView);
}

@Override
public void onBindViewHolder(final WSAdapter.ImageViewHolder holder, int position) {
    uploadCurrent = filesList.get(position);
    if (!uploadCurrent.getAbsolutePath().endsWith(".mp4")) {
        Bitmap myBitmap = BitmapFactory.decodeFile(uploadCurrent.getAbsolutePath());
        holder.imageView.setImageBitmap(myBitmap);
    }else{
        Uri video = Uri.parse(uploadCurrent.getAbsolutePath());
        holder.videoView.setVideoURI(video);
    }

    holder.imageView.setOnClickListener(new View.OnClickListener() 
{
        @Override
        public void onClick(View view) {
            Intent go = new Intent(mContext, WSImageDetailsActivity.class);
            go.putExtra("path",uploadCurrent.getAbsolutePath());
            mContext.startActivity(go);
        }
    });
}
@Override
public int getItemCount() {
    return filesList.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
    //public TextView textViewName;
    public ImageView imageView;
    public VideoView videoView;
    public ImageViewHolder(View itemView) {
        super(itemView);
        //textViewName = itemView.findViewById(R.id.text_view_name);
        imageView = itemView.findViewById(R.id.image_view_ws);
        videoView = itemView.findViewById(R.id.video_view_ws);
    }
}
}

WSImageDetailsActivity.java

package com.example.mokkajokes.ui.whatsappstatus;

public class WSImageDetailsActivity extends AppCompatActivity {
public TextView textViewName;
public ImageView imageView;
public String name,url;
public VideoView videoView;
Bundle extras=null;
public String path;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ws_image_details_view);
    extras = getIntent().getExtras();
    imageView = findViewById(R.id.image_view_ws);
    videoView = findViewById(R.id.video_view_ws);
    path = extras.getString("path");

    imageView.setImageDrawable(null);
    videoView.clearFocus();
    if(!path.endsWith(".mp4")) {
        videoView.setVisibility(View.GONE);
        Bitmap myBitmap = BitmapFactory.decodeFile(path);
        imageView.setImageBitmap(myBitmap);
    }
    else{
        imageView.setVisibility(View.GONE);
        videoView.setVideoURI(Uri.parse(path));
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.setLooping(true);
                videoView.start();
            }
        });
    }
    getIntent().removeExtra("path");
}
}

fragment_ws.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="ui.whatsappstatus.GalleryFragment">

<TextView
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:layout_marginRight="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:text="@string/title_pics" />

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewMedia"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"/>

</RelativeLayout>

ws_image_item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_weight="1">
    <ImageView
        android:id="@+id/image_view_ws"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:scaleType="centerInside"
        android:adjustViewBounds="true"/>

    <VideoView
        android:id="@+id/video_view_ws"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:scaleType="centerInside"
        android:layout_weight="1" />

</LinearLayout>
</androidx.cardview.widget.CardView>

ws_image_details_view.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/image_view_ws"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"/>

    <VideoView
        android:id="@+id/video_view_ws"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>
</androidx.cardview.widget.CardView>

Solution

  • You store File uploadCurrent in adapter scope, it means onClick always get info of last view holder bind to adapter, try to move File uploadCurrent into onBindViewHolder and remove it in outer.

    @Override
    public void onBindViewHolder(final WSAdapter.ImageViewHolder holder, int position) {
        final File uploadCurrent = filesList.get(position);
        if (!uploadCurrent.getAbsolutePath().endsWith(".mp4")) {
            Bitmap myBitmap = BitmapFactory.decodeFile(uploadCurrent.getAbsolutePath());
            holder.imageView.setImageBitmap(myBitmap);
        }else{
            Uri video = Uri.parse(uploadCurrent.getAbsolutePath());
            holder.videoView.setVideoURI(video);
        }
    
        holder.imageView.setOnClickListener(new View.OnClickListener() 
    {
            @Override
            public void onClick(View view) {
                Intent go = new Intent(mContext, WSImageDetailsActivity.class);
                go.putExtra("path",uploadCurrent.getAbsolutePath());
                mContext.startActivity(go);
            }
        });
    }