Search code examples
javaandroidandroid-imageviewclasscastexception

Fixing error with Gridlayout casting to ImageView


I have the .xml file set up as

<GridLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:columnCount="4"
    android:rowCount="6"
    android:onClick="dropIn"
    android:layout_alignParentEnd="true"
    android:id="@+id/gridLayout">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="80dp"
        android:layout_height="70dp"
        android:layout_column="0"
        tools:layout_editor_absoluteX="288dp"
        tools:layout_editor_absoluteY="180dp"
        android:layout_row="0"
        android:onClick="dropIn"
        android:contentDescription="@null"
        android:tag="1"
        app:srcCompat="@drawable/stone" />

Anyways, I have plenty more of ImageViews and the thing that makes them different is the id and the tag. I decided to have them recognized by code by their tag. So this is what I currently have:

int[] gameState = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};

public void dropIn(View view) {

    ImageView counter = (ImageView) view;
    counter.setImageResource(R.drawable.stone);

    int tappedCounter = Integer.parseInt(counter.getTag().toString());
    try {
        if (gameState[tappedCounter] == 2 && gameIsActive) {

            gameState[tappedCounter] = 3;
            countMe = countMe - 1;
            counter.setVisibility(View.INVISIBLE);
        } else if (gameState[tappedCounter] == 3 && gameIsActive) {

            Toast.makeText(MainActivity.this, "That field is already played!",
                    Toast.LENGTH_SHORT).show();
        }
    } catch (Exception e) {
        Toast.makeText(MainActivity.this, "Oho!",
                Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }

This all works fine, except when I click an ImageView that has already been clicked and is now invisible, it crashes the app with the following message:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.nedim.lastonestanding, PID: 9758
              java.lang.IllegalStateException: Could not execute method for android:onClick
                  at android.view.View$DeclaredOnClickListener.onClick(View.java:5374)
                  at android.view.View.performClick(View.java:6294)
                  at android.view.View$PerformClick.run(View.java:24770)
                  at android.os.Handler.handleCallback(Handler.java:790)
                  at android.os.Handler.dispatchMessage(Handler.java:99)
                  at android.os.Looper.loop(Looper.java:164)
                  at android.app.ActivityThread.main(ActivityThread.java:6494)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
               Caused by: java.lang.reflect.InvocationTargetException
                  at java.lang.reflect.Method.invoke(Native Method)
                  at android.view.View$DeclaredOnClickListener.onClick(View.java:5369)
                  at android.view.View.performClick(View.java:6294) 
                  at android.view.View$PerformClick.run(View.java:24770) 
                  at android.os.Handler.handleCallback(Handler.java:790) 
                  at android.os.Handler.dispatchMessage(Handler.java:99) 
                  at android.os.Looper.loop(Looper.java:164) 
                  at android.app.ActivityThread.main(ActivityThread.java:6494) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
               Caused by: java.lang.ClassCastException: android.widget.GridLayout cannot be cast to android.widget.ImageView
                  at com.nedim.lastonestanding.MainActivity.dropIn(MainActivity.java:32)
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at android.view.View$DeclaredOnClickListener.onClick(View.java:5369) 
                  at android.view.View.performClick(View.java:6294) 
                  at android.view.View$PerformClick.run(View.java:24770) 
                  at android.os.Handler.handleCallback(Handler.java:790) 
                  at android.os.Handler.dispatchMessage(Handler.java:99) 
                  at android.os.Looper.loop(Looper.java:164) 
                  at android.app.ActivityThread.main(ActivityThread.java:6494) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
Application terminated.

From what I understand, the Image from the ImageView disappears and now I am clicking on the GridLayout and not the ImageView which causes it to crash as it's not the thing that I want to be working with. I also suppose that the problem is that counter is making all views become ImageViews, but I am not sure how I could fix this. Any ideas? Thanks!

EDIT: The onCreate method

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

    TextView winMessage = findViewById(R.id.winMessage);
    winMessage.setText("Let's play! It's Player " + activePlayer + "'s turn.");
}

Solution

  • You have the same attribute android:onClick="dropIn" declared both for GridLayout and ImageView. The 1st one causes the ClassCastException at the line ImageView counter = (ImageView) view;