Search code examples
javaandroidimageviewandroid-imageview

Changing 2D array of images OnClick


I'm a beginner with Android development (and Java). I've a number of ImageView in a layout (2d array of images). What I'm trying to implement is, each time when I click on an ImageView, it should set an image from an array based on some logic with current image being displayed (e.g. next image in array, with each click). I have googled and managed to do this but it looks rather long.

public class GameActivity extends AppCompatActivity {
    private int [] inputTiles = {R.drawable.one, R.drawable.two, ...// more images};
    Random r = new Random();
    int matSize = 5;
    int[][] indexMat = new int[matSize][matSize];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        for (int i=0; i<matSize; i++) {
            for (int j=0; j<matSize; j++) {
                indexMat[i][j] = r.nextInt(10);
            }
        }

        final ImageView tile00 = findViewById(R.id.tile00);
        tile00.setImageResource(inputTiles[indexMat[0][0]]);
        tile00.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            indexMat[0][0] = (indexMat[0][0]+1)%5;
            tile00.setImageResource(inputTiles[indexMat[0][0]]);
            }
        });

        final ImageView tile01 = findViewById(R.id.tile01);
        tile01.setImageResource(inputTiles[indexMat[0][1]]);
        tile01.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                indexMat[0][1] = (indexMat[0][1]+1)%5;
                tile01.setImageResource(inputTiles[indexMat[0][1]]);
            }
        });

        ...// a lot more ImageViews

    }
}

Say I'm displaying 5x5 grid of images. I've the available images in an array inputTiles and a 5x5 array indexMat to store the index of current image at a location i, j. Then, for each ImageView I'm listening for click and choosing another image to display from array. This is working perfectly, but I have to write "clicklisten and action" block 25 times, in this particular example. It'd be really great if there's a way to loop this so that I can have any n x n grid.

I tried looping after a bit googling, by keeping ImageView in a 5x5 array and looping over it, but the loop variables doesn't seem to go inside the setOnClickListener() function. It says I need to make i and j as final but then it becomes constants, so doesn't work. Below code is what I tried, but it doesn't work that way.

final ImageView[][] tiles = {{findViewById(R.id.tile00), findViewById(R.id.tile01), findViewById(R.id.tile02),...},
        {findViewById(R.id.tile10), ...,}};

for (int i=0; i<3;i++){
    for (int j=0; j<3; j++){
        tiles[i][j].setImageResource(inputTiles[indexMat[i][j]]);
        tiles[i][j].setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                indexMat[i][j] = //doesn't work
            }
        });
    }
}

Any ideas?


Solution

  • The simplest way of doing this is to have a RecyclerView with a GridLayoutManager. Here's a nice example about how you can achieve your desired functionality in a RecyclerView.

    Once you are setting these images in your RecyclerView, you can easily manage the click listener in your onBindViewHolder function, based on the position you have clicked.