简体   繁体   中英

Android: Array of dynamically generated ImageButtons only returns info from last one created when clicked

I have an activity that generates and displays a GridLayout of custom ImageButtons called MapCells (It's a game map, surprise.) The MapCells are randomly generated and contain some variables that relate to terrain type as well as looking different (the image). What happens when I run my code is that I get my lovely random map, and when I click on the cells they should toast up their id on the screen (a diagnostic aid) as well as getting their stored variables and setText-ing them to some TextViews in the same activity. How it actually works when I click on the MapCells is that they toast the unique id (as expected) and have their unique appearances, but the terrain values that display are of the last MapCell that was generated in all cases. I thought this was the result of my 'for' loop creating all of the MapCells as the variable q (visible in commented out code) which I was just overwriting every loop, so I rewrote it to the code below, however, I am getting the same problem. Other questions I have looked at seemed to indicate that giving them the ids would solve this. Any ideas?

package com.<redacted>

import java.util.Random;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

public class MapScreen extends Activity implements OnClickListener{
    private static int dimen = 110; //the side length of map cells
    private int currentFood;
    private String currentName;
    private MapCell[] storage = new MapCell[18];//keep the cells in here

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map_screen); //the xml

  //It's Randy the randomizer!
    Random randy = new Random();

    //Generate 6 random MapCells per row for use in our map.
    //MapCell q; -this is old and unused now
    for(int i=0; i<=5; i++){
        //q = new MapCell(randy.nextInt(4), this); //create and randomize
        //q.setId(i); //issue identity
        storage[i] = new MapCell(randy.nextInt(4), this); //shove it in the array
        storage[i].setId(i);
        storage[i].setOnClickListener((OnClickListener) this);
        //q.setOnClickListener((OnClickListener) this);
        ((TableRow)findViewById(R.id.mapRow01)).addView(storage[i], dimen, dimen); //add cell to display
    }
    for(int j=0; j<=5; j++){
        //q = new MapCell(randy.nextInt(4), this);
        //q.setId(j+6);
        //storage[q.getId()] = q; //shove it in the array
        //q.setOnClickListener((OnClickListener) this);
        storage[j+6] = new MapCell(randy.nextInt(4), this); //shove it in the array
        storage[j+6].setId(j+6);
        storage[j+6].setOnClickListener((OnClickListener) this);
        ((TableRow)findViewById(R.id.mapRow02)).addView(storage[j+6], dimen, dimen); //add cell to display
    }
    for(int k=0; k<=5; k++){
        //q = new MapCell(randy.nextInt(4), this);
        //q.setId(k+12);
        //storage[q.getId()] = q; //shove it in the array
        //q.setOnClickListener((OnClickListener) this);
        storage[k+12] = new MapCell(randy.nextInt(4), this); //shove it in the array
        storage[k+12].setId(k+12);
        storage[k+12].setOnClickListener((OnClickListener) this);
        ((TableRow)findViewById(R.id.mapRow03)).addView(storage[k+12], dimen, dimen); //add cell to display
    }
}

public void displayCell(MapCell view){
    //get the cell name view and then set its text to be the name of the clicked cell
    try{ //we need to try in case it feeds in a non-MapCell view
        currentName = storage[view.getId()].getName();
        ((TextView)findViewById(R.id.mapDisplayName)).setText(currentName);
        currentFood = storage[view.getId()].getFood();
        ((TextView)findViewById(R.id.mapDisplayFood)).setText(String.valueOf(currentFood));
        Toast.makeText(this, "Cell " + String.valueOf(view.getId()), Toast.LENGTH_SHORT).show(); //diagnostic line
    }
    catch (Exception x){
        //frowny time
        Toast.makeText(this, "Something Broke on cell " + String.valueOf(view.getId()) + " :(", Toast.LENGTH_SHORT).show();
    }
}

public void onClick(View v){//when we click a MapCell
    displayCell((MapCell)v);// feed it in
}

}

That's the relevant class. I can show you MapCell if you ask, but it's just an ImageButton with a few added variables along for the ride with getters. These variables are set by switch case using the random integer provided in the constructor.

As I see nothing wrong with your code, I'll take a shot in the dark. In your MapCell class, is the variable that holds terrain values defined using the static modifier?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM