0

I am having a problem that I want to random an image array in Recyclerview onBindViewHolder, everything is working fine but it is repeating random images from the array like 2 images coming 2 times. i am using it in vertical recyclerview for showing text and images to their exact position Like if i have 2 array one is string and the other one is int for images, so i want both array position will random simultaneously at same position but without duplicates my code is doing everything perfectly but its repeating the images.

This is my full code

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewwHolder>  {
     private int [] arraylist;
    private Context ctx;
   private ImageView name;
    private TextView textView;
   private   String [] text ;



    public MyAdapter(int[] arraylist, String []text,Context ctx) {
        this.arraylist = arraylist;
        this.text = text;
        this.ctx = ctx;
    }
    @NonNull
    @Override
    public ViewwHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view= LayoutInflater.from(ctx.getApplicationContext()).inflate(R.layout.row,  viewGroup, false) ;
        return new ViewwHolder(view);    }

    @Override
    public void onBindViewHolder(@NonNull ViewwHolder viewwHolder, final int i) {



        Random random=new Random();
      final int po=random.nextInt(arraylist.length);
        name.setImageResource(arraylist[po]);
        textView.setText(text[po]);

        name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                    Intent intent= new Intent(ctx, second.class);
                           intent.putExtra("imageposition", arraylist[po]);
                           intent.putExtra("textposition",text[po]);
                           ctx.startActivity(intent);


            }
        });

    }

    @Override
    public int getItemCount() {
        return arraylist.length;
    }


    public class ViewwHolder extends RecyclerView.ViewHolder {
        public ViewwHolder(@NonNull View itemView) {
            super(itemView);
            name=itemView.findViewById(R.id.itemoneimageone);
            textView=itemView.findViewById(R.id.text);
        }
    }



}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62

2 Answers2

0

You can remove the image from the list after it has been used.

private ArrayList<Integer> arraylist; // use a dynamic array.


final int po = random.nextInt(arraylist.size());
int imageResource = arraylist.get(po);
arraylist.remove(po); // if you don't want to lose it, you can store it in another ArrayList before removal
name.setImageResource(imageResource);
Israel dela Cruz
  • 794
  • 1
  • 5
  • 11
0

If you don't want the images to repeat, then you don't want to randomly select an image at each call to onBindViewHolder. Instead, you want to shuffle the images (and associated texts) once and go through the shuffled array(s) in order. Since you have both an image array and a text array (and presumably need to keep them in sync) I recommend creating an array of integers from 0 through arraylist.length-1 and then shuffling that. (You can find code to shuffle an int[] in the answers to this question.) You would do this outside of onBindViewHolder and store the shuffled indexes in a member field (let's call it shuffledArray). Then instead of

final int po=random.nextInt(arraylist.length);

use

final int po = shuffledArray[i];

An alternative (better, in my view) would be to create an array of image/text pairs and store it in an ArrayList of an appropriate type. You can then shuffle the list using Collections.shuffle. Once again, this would be done once outside of onBindViewHolder.

For some reason, Java has a Collections.shuffle method but doesn't have an Arrays.shuffle method.

EDIT: Now that I see your entire class, here's how I would change it:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewwHolder>  {
    ...

    private int[] shuffled;

    public MyAdapter(int[] arraylist, String []text,Context ctx) {
        this.arraylist = arraylist;
        this.text = text;
        this.ctx = ctx;
        shuffled = new int[arraylist.length];
        for (int i = 0; i < arraylist.length; i++) shuffled[i] = i;
        shuffle(shuffled);
    }

    private static void shuffle(int[] array) {
        Random rnd = ThreadLocalRandom.current();
        for (int i = array.length - 1; i > 0; i--) {
          int index = rnd.nextInt(i + 1);
          int tmp = array[index];
          array[index] = array[i];
          array[i] = tmp;
        }
    }
}

Then, as before, inside onBindViewHolder, change the way you set po to:

final int po = shuffled[i];

Everything else can remain the same.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521