-3

I'm writing a memory game app for android and calling setImageResource() method of an ImageButton often has no effect whatsoever.

So the idea is you have a random number of hidden images on screen (in this particular case we have 4 buttons), implemented as ImageButtons with R.drawable.image_default as their image resource and when the button "Start" gets clicked the game begins. When user clicks one button it shows it's image. When user clicks another one, it shows the image behind it and after a brief delay one of two things can happen:

  1. Shown images are the same and they disappear from the screen
  2. Shown images are different so both buttons containing them revert their images to image_default

The problem is this - when user clicks on the first button, setImageResource() gets called and it (the button) changes it's image as it is supposed to, but when the user clicks the SECOND button (one of the other three buttons facing down), setImageResource() gets called again but image on the button doesn't change.

Despite this, everything else works as if the change happened (meaning if they (images) are the same, buttons disappear from the screen, but if they are different, button images just get flipped face down (simulated by image resource getting set back to image_default)).

The question is why does the button that is clicked second not change it's image resource and get redrawn on screen?

Here is my implementation

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;

public class ButtonExample extends AppCompatActivity implements View.OnClickListener {

private ImageButton imageButton0, imageButton1, imageButton2, imageButton3;

private ImageButton firstImage, secondImage;
private Button buttonStart;

private int[] arrayOfImages = {R.drawable.image0, R.drawable.image0, R.drawable.image1, R.drawable.image1};

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

    imageButton0 = (ImageButton) findViewById(R.id.imageButton0);
    imageButton0.setOnClickListener(this);
    imageButton1 = (ImageButton) findViewById(R.id.imageButton1);
    imageButton1.setOnClickListener(this);
    imageButton2 = (ImageButton) findViewById(R.id.imageButton2);
    imageButton2.setOnClickListener(this);
    imageButton3 = (ImageButton) findViewById(R.id.imageButton3);
    imageButton3.setOnClickListener(this);

    buttonStart = (Button) findViewById(R.id.button_start);
    buttonStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setDefaultBackgrounds();
        }
    });
}

@Override
public void onClick(View v) {
    //if this is the first image to be shown
    if (firstImage == null) {
        firstImage = (ImageButton) v;
        showImage(firstImage);
    } else {
        //else the first is already showing, so this must be the second image
        secondImage = (ImageButton) v;

        //if an already open image has been clicked
        if (firstImage.equals(secondImage)) {
            //just hide the image
            hideImage(firstImage);
        } else {
            /*
            else show the second image.
            (This is where the problem lies, this method gets called but the ImageButton does not get redrawn)
             */
            showImage(secondImage);

            //sleep so to let the user see what image he clicked on
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //if the user opened two same images
            if (equalImages(firstImage, secondImage)) {
                //make the buttons invisible
                firstImage.setVisibility(View.INVISIBLE);
                secondImage.setVisibility(View.INVISIBLE);
            } else {
                //else just hide the images
                hideImage(firstImage);
                hideImage(secondImage);
            }
        }
        firstImage = null;
        secondImage = null;
    }
}

//initialize the button images
private void setDefaultBackgrounds() {
    imageButton0.setImageResource(R.drawable.image_default);
    imageButton0.setVisibility(View.VISIBLE);
    imageButton0.setTag(arrayOfImages[0]);

    imageButton1.setImageResource(R.drawable.image_default);
    imageButton1.setVisibility(View.VISIBLE);
    imageButton1.setTag(arrayOfImages[1]);

    imageButton2.setImageResource(R.drawable.image_default);
    imageButton2.setVisibility(View.VISIBLE);
    imageButton2.setTag(arrayOfImages[2]);

    imageButton3.setImageResource(R.drawable.image_default);
    imageButton3.setVisibility(View.VISIBLE);
    imageButton3.setTag(arrayOfImages[3]);
}

//show the image
private void showImage(ImageButton ib) {
    if (ib.equals(imageButton0)) {
        ib.setImageResource(arrayOfImages[0]);
    } else if (ib.equals(imageButton1)) {
        ib.setImageResource(arrayOfImages[1]);
    } else if (ib.equals(imageButton2)) {
        ib.setImageResource(arrayOfImages[2]);
    } else {
        ib.setImageResource(arrayOfImages[3]);
    }
}

//are images the same
private boolean equalImages(ImageButton ib1, ImageButton ib2) {
    return ib1.getTag().equals(ib2.getTag());
}

//hide the image
private void hideImage(ImageButton ib) {
    ib.setImageResource(R.drawable.image_default);
}
}

And here is the layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="30dp"
android:layout_marginEnd="30dp"
android:layout_marginStart="30dp"
android:layout_marginTop="30dp"
android:background="#cdcdcb"
android:baselineAligned="false"
android:orientation="vertical"
tools:context="com.example.schonn.myproject.ButtonExample">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="3">


    <Button
        android:id="@+id/button_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="97dp"
        android:text="@string/start" />
</RelativeLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="horizontal">

    <ImageButton
        android:id="@+id/imageButton0"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:adjustViewBounds="true" />

    <ImageButton
        android:id="@+id/imageButton1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:adjustViewBounds="true" />
</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="horizontal">

    <ImageButton
        android:id="@+id/imageButton2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:adjustViewBounds="true" />

    <ImageButton
        android:id="@+id/imageButton3"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:adjustViewBounds="true" />
</LinearLayout>

</LinearLayout>
Schonn
  • 1
  • 4

1 Answers1

1

May I suggest an alternate approach to your Problem. From your Question, what i am getting is that when you click on image1, it should change to image2, and when you click on image2, it should change back to image1. So The approach i would use is this

Firstly put both of the images in a FrameLayout. And then make the image2 invisible by default Image2.setVisibility(View.INVISIBLE) . So that you only see Image1. Now when you click on Image1, then in the onClick Listener of Image1, Set the Image1 to be invisible and Image2 be Visible . Then in the Image2, OnclickListener, set the Image2 to be Invisible and Image1 to be Visible

Nick Asher
  • 726
  • 5
  • 19