Нажатие одной кнопки влияет на все

#android #android-imagebutton

#Android #android-imagebutton

Вопрос:

Итак, у меня есть это приложение для Android, которое предположительно является настольной игрой. На нем есть несколько кнопок, и при выборе я хочу, чтобы выбранная из них получила границу. Но по какой-то причине при нажатии на единицу он выбирает все или просто не отменяет выбор. Что я забыл сделать или делаю неправильно? Потому что, по логике вещей, это не должно ничего менять, кроме этой плитки. У них нет цикла For с setImageBitmap!

OnClickListener:

 //set onCLickListener on each tile
public void setOnClickListenerOnTile(TileClass tileI){
    ImageButton tile = (ImageButton) findViewById (tileI.getId());
    tile.setOnClickListener(new OnClickListener (){
        @Override
        public void onClick (View V){
            Log.i(TAG, "tileOnClick");
            ImageButton tile = (ImageButton) findViewById (V.getId());

            /*Following code checks if...
             *1. if no tile is selected
             *2. if the tile that is clicked is also the one that is selected
             *3. if the tile selected is different than the one that is clicked*/
            //if 1. happens, then add boarder
            if (selectedTile == 0){
                Log.i(TAG, "First Choice: 1");
                //set tile with boarder
                tile.setImageBitmap(modifyTile(1,color.blue, mapTile[findTileById(tile.getId(), mapTile)].tilePic));
                //remember what tile is selected
                selectedTile = V.getId();
            }
            //else if 2. happens, then remove boarder
            else if (selectedTile == V.getId()){
                Log.i(TAG, "First Choice: 2");
                //set tile without boarder
                tile.setImageBitmap(mapTile[findTileById(tile.getId(), mapTile)].tilePic);
                tile.setImageBitmap(blankTileBitmap);
                tile.refreshDrawableState();
                //remember what tile is selected
                selectedTile = 0;
            }
            //else if 3. happens, then remove the boarder on the selectedTile and add boarder on the clickedTile
            else if (selectedTile != V.getId() amp;amp; selectedTile != 0){
                Log.i(TAG, "First Choice: 3");
                //remove old boarder
                ImageButton tempIB = (ImageButton) findViewById (selectedTile);
                tempIB.setImageBitmap(mapTile[findTileById(selectedTile, mapTile)].tilePic);
                //add new boarder
                tile.setImageBitmap(modifyTile(1,color.blue, mapTile[findTileById(tile.getId(), mapTile)].tilePic));
                //remember what tile is selected
                selectedTile = V.getId();
            }
        }
    });
}
  

modifyTile:

 //Method function:
//to modify a tile
//modificationNum code:
//1: add boarders
//2: remove boarders
//Param: accepts the type of modifications as first parameter, 
//color ID as listed in color resource (not Color),
//and a bitmap of the tile
//
public Bitmap modifyTile (int modificationNum, int color, Bitmap bitmap){
    int count, count2;
    Log.i(TAG, "modifyTile has been called!");
    //first, find out which modification todo
    //if modificationNum == 1,  then it is to add a border
    if (modificationNum == 1){
        if (bitmap == null){
            Log.i(TAG, "null error");
        }
        //set tile boarders on the top
        for (count = 1; count < tileLength; count  ){
            bitmap.setPixel(count, 1, getResources().getColor(color));
        }
        //sides...
        for (count = 1; count < (tileLength); count  ){
            bitmap.setPixel(1, count, getResources().getColor(color));
            bitmap.setPixel((tileLength - 1), count, getResources().getColor(color));
        }

        //set tile boarders on the bottom
        for (count = 1; count < tileLength; count  ){
            bitmap.setPixel(count-1, tileLength-1, getResources().getColor(color));
        }
    }
  

getAllTileId:

 //get id of every tile (may take a long time) (not done)
public int[] getAllTileId (){
    int count, count2;
    Log.i(TAG, "getAllTileId has been called!");
    //set up variables...
    //have to set up a view for TableLayout so that I can find the tile's id using Tags (it has to be it's childs)
    View v = (TableLayout) findViewById (R.id.mapTable);
    ImageButton imageButton;
    int temp, globalCount;
    int results[] = new int[50];
    for (count = 0, globalCount = 0; count < 9; count   ){
        if (count % 2 == 0){
            temp = 6;
        }
        else{
            temp = 5;
        }
        for (count2 = 0; count2 < temp; count2  , globalCount  ){
            imageButton = (ImageButton) v.findViewWithTag ("land"   (count   1)   (count2   1));

            results[globalCount] =  imageButton.getId();
            Log.i(TAG, "land #"   (count 1)   (count2 1)   "'s id = "   results[globalCount]); 
        }
    }
    Log.i(TAG, "getAllTileId length"   results.length);
    return results;
}
  

findTileById:

 //find a tile in an array using it's id
public int findTileById (int id, TileClass[] map){
    Log.i(TAG, "findTileById has been called!");
    int count=0;
    for (count = 0; count < map.length amp;amp; map[count].getId() != id; count  );
    if (count >= map.length){
        Log.i(TAG, "findTileById FAIL");
    }
    return count;
}
  

Редактировать:
Вот onCreate:

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


    //**TEST AREA, DELETE AFTER**

    //**TEST AREA END**

    //get the way to convert from dp to pixels and set up tileLength (in pixels)
    metrics = getResources().getDisplayMetrics();
    dpToPixels = metrics.density;
    tileLength = (int) Math.ceil(44 * dpToPixels);

    //set tilePic dimensions
    tilePic = new int[tileLength * tileLength];
    Log.i(TAG, "tileLength = "   tileLength   " and dpToPixels = "   dpToPixels);

    //set up colors
    blue = getResources().getColor(R.color.blue);

    //set up blank selected tile bitmap
    selectedTileBitmap = Bitmap.createBitmap(tileLength, tileLength, Bitmap.Config.ARGB_8888);
    //set tile boarders
    selectedTileBitmap = modifyTile (1, color.blue, selectedTileBitmap);

    //set up blank tile bitmap
    blankTileBitmap = Bitmap.createBitmap(tileLength, tileLength, Bitmap.Config.ARGB_8888);
    for (count = 0; count < tileLength; count  ){
        for (count2 = 0; count2 < tileLength; count2  ){
            blankTileBitmap.setPixel(count, count2, getResources().getColor(color.white));
        }
    }

    //first... get map tile ids...
    mapTileId = new int [50];
    mapTileId = getAllTileId ();

    //set up mapTile
    mapTile = new TileClass[50];
    for (count = 0; count < 50; count  ){

        //first... get the tile (which is an ImageButton)
        tempIB = (ImageButton) findViewById (mapTileId[count]);
        //next step is to create a stringModifier to get the coordinates of the tile through it's tag
        stringModifier = new StringBuilder (tempIB.getTag().toString());
        //create the tile...
        mapTile [count] = new TileClass (tempIB.getId(), Integer.parseInt(stringModifier.substring(4, 5)), Integer.parseInt(stringModifier.substring(5,6)), blankTileBitmap);
        Log.i(TAG, "count = "   count);
        Log.i(TAG, "test count"   mapTile[count].getId());
    }

    //set up all the bitmap of the tiles on screen
    for (count = 0; count < 50; count  ){
        tempIB = (ImageButton) findViewById (mapTile [count].getId());
        tempIB.setImageBitmap(mapTile[count].tilePic);
    }

    Log.i(TAG, "Finished setting up mapTile.");
    //get id of every tile

    //set up each tile with an onClick
    for (count = 0; count < 50; count  ){
        setOnClickListenerOnTile(mapTile[count]);
    }

}
  

Комментарии:

1. Я подозреваю mapTile[x].tilePic , что все x ссылаются на одно и то же растровое изображение. Когда вы меняете один, все они меняются. Не могли бы вы проверить это или опубликовать свой код, в котором вы инициализируете mapTile и его изображение.

2. Почему это должно ссылаться на одно и то же растровое изображение? Я настроил каждую часть массива с другим TileClass. О, а также, иногда, если я нажимаю определенную кнопку справа, щелкает только та, которая нажимается как обычно, но все равно не отменяет выбор.

Ответ №1:

Хорошо, я нашел свою проблему. Пользователь может нажать кнопку до завершения onCreate, что также происходит до инициализации множества массивов, которые используются для поиска / инициализации других кнопок. Итак, когда пользователь нажимает кнопку слишком быстро, массив ссылается на каждую кнопку.