为什么这有时不起作用?

Ruc*_*nia 15 java optimization android if-statement bitmap

TL; DR我有很多按钮,我正在交换它们的图像.出于某种原因,我的代码仅适用于某些手机,而不适用于其他手机.

我的应用程序使用以下代码比较图像按钮上的图像:

onCreate:

redsquare = getResources().getDrawable(R.drawable.redsquare);
bitred = ((BitmapDrawable) redsquare).getBitmap();
Run Code Online (Sandbox Code Playgroud)

onClick (v点击按钮)

ClickGround = v.getBackground(); //Get the background of button clicked
//the bitmap background of the button clicked
BitClick = ((BitmapDrawable) ClickGround).getBitmap(); 
Run Code Online (Sandbox Code Playgroud)

然后,稍后在onClick中,我检查用户是否通过这样做点击了redSquare:

if (BitClick == bitred) { //Make sure it is the red square that user clicked
}
Run Code Online (Sandbox Code Playgroud)

我已经在我的模拟器和华为手机上进行了测试,效果很好.当我在另一部手机(LG g3)上测试时,if语句没有通过.为什么结果不同?我的手机中的图像是否被搞砸了?

Ste*_*n C 11

首先,Resources.getDrawable(int)弃用.它可能与您的问题无关,但您应该修复它.

如果使用比较位图来==比较对象标识.如果==测试给你false,那意味着你正在比较不同的对象.毫无疑问.

你的片段没有足够的背景来确定,但这里有一些可能性:

  1. 代码中的某些内容导致分配不同的值bitred.

  2. bitred两个代码片段中的标识符不表示相同的Java变量.

  3. 您假设用作红色背景的"红色"位图始终是同一个对象是无效的.

让我们假设你已经消除了1.和2.以上,并专注于3.怎么会发生这种情况?好吧,我们看不到相关的代码(你随机交换按钮图像的地方),但我可以想到几个可能性:

  • 您可以Resources重复获取位图.
  • 您调用切换位图的方法可能是创建/设置副本.
  • 获取单击按钮位图的方法可能是返回副本.

并且由于上述每个操作都可能依赖于可能表现不同的API实现(因为javadoc允许这样做),因此应用程序的行为可能取决于平台.


那么解决方案是什么?

假设,如果你能弄清楚导致使用不同位图对象的原因,你可以解决它.但是,虽然您的代码仍然依赖于未指定的行为,但它有可能在其他手机上中断...

更好的解决方案是更改您的应用程序,以便不依赖于使用==比较Bitmap对象.例如:

  • 将标记与每个按钮相关联.

     button1.setTag("one");
     button2.setTag("two");
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建一个HashMap从按钮的标签映射到该按钮的当前颜色.HashMap是应用程序"模型"状态的一部分.

    Map colors = new HashMap();
    ...
    colors.put("one", "red");
    colors.put("two", "blue");
    
    Run Code Online (Sandbox Code Playgroud)
  • 更改按钮的图像位图时,请对地图进行相应的更新.

    // After swap the images of button1 and button2 ...
    String c1 = colors.get("one");
    String c2 = colors.get("two");
    colors.put("one", c2);
    colors.put("two", c1);
    
    Run Code Online (Sandbox Code Playgroud)
  • 在onClick方法中,使用map查找按钮的当前颜色,而不是通过比较Bitmap对象来尝试找出它.

    if (colors.get(v.getTag()).equals("red")) {
        // it is red!
    }
    
    Run Code Online (Sandbox Code Playgroud)

(请注意,这与Biju Parvathy所暗示的相近,但他没有明确说明如何处理按钮颜色/图像的变化.)


Let*_*tor 7

你可以,我在比较代码中进行了一些小改动,使其适用于所有设备.

Bitmap BitRed = ((BitmapDrawable)getResources().getDrawable(R.drawable.redsquare)).getBitmap();

Bitmap BitClick = ((BitmapDrawable) v.getBackground()).getBitmap();

if (BitClick.sameAs(BitRed)) 
{ 
    //Your Button with Red Square Clicked
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅SameAs函数.希望这对你有所帮助.