#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, что также происходит до инициализации множества массивов, которые используются для поиска / инициализации других кнопок. Итак, когда пользователь нажимает кнопку слишком быстро, массив ссылается на каждую кнопку.