Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/194.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这有时不起作用? TL;博士,我有很多按钮,我正在交换它们的图像。出于某种原因,我的代码只在某些手机上有效,而在其他手机上无效。_Java_Android_If Statement_Optimization_Bitmap - Fatal编程技术网

Java 为什么这有时不起作用? TL;博士,我有很多按钮,我正在交换它们的图像。出于某种原因,我的代码只在某些手机上有效,而在其他手机上无效。

Java 为什么这有时不起作用? TL;博士,我有很多按钮,我正在交换它们的图像。出于某种原因,我的代码只在某些手机上有效,而在其他手机上无效。,java,android,if-statement,optimization,bitmap,Java,Android,If Statement,Optimization,Bitmap,我的应用程序使用以下代码比较imagebuttons上的图像: onCreate: redsquare = getResources().getDrawable(R.drawable.redsquare); bitred = ((BitmapDrawable) redsquare).getBitmap(); onClick (v按钮是否已单击) 然后,在稍后的onClick中,我通过执行以下操作检查用户是否单击了红方块: if (BitClick == bitred) { //Make sur

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

onCreate

redsquare = getResources().getDrawable(R.drawable.redsquare);
bitred = ((BitmapDrawable) redsquare).getBitmap();
onClick
v
按钮是否已单击)

然后,在稍后的onClick中,我通过执行以下操作检查用户是否单击了红方块:

if (BitClick == bitred) { //Make sure it is the red square that user clicked
}

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

首先,
Resources.getDrawable(int)
是。这可能与您的问题无关,但您应该解决它

如果使用
=
比较位图,则比较对象标识。如果
=
测试为您提供了
false
,则表示您正在比较不同的对象。这是毫无疑问的

您的代码片段没有提供足够的上下文来确定,但以下是一些可能性:

  • 代码中的某些内容导致将不同的值分配给

  • 两段代码中的
    标识符并不表示相同的Java变量

  • 假设用作红色背景的“红色”位图始终是同一个对象是无效的

  • 假设您已经消除了1。二,。以上,重点关注3。怎么会这样?嗯,我们看不到相关的代码(您可以随机交换按钮图像),但我可以想到几种可能性:

    • 您可以重复从
      资源
      获取位图
    • 为切换位图而调用的方法可能是创建/设置副本
    • 为获取单击按钮的位图而调用的方法可能会返回一个副本
    而且,由于上述每个操作都可能依赖于行为可能不同的API实现(因为javadoc允许),因此应用程序的行为可能依赖于平台


    那么解决方案是什么呢

    假设,如果您能够找出导致使用不同位图对象的原因,您就可以解决这个问题。然而,虽然您的代码仍然依赖于未指定的行为,但它有可能在其他手机上被破坏

    更好的解决方案是更改应用程序,使其不依赖于使用
    =
    来比较
    位图
    对象。例如:

    • 将标签与每个按钮关联

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

    • 更改按钮的图像位图时,对贴图进行相应的更新

      // 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);
      
    • 在onClick方法中,使用贴图查找按钮的当前颜色,而不是通过比较
      Bitmap
      对象来尝试找出它

      if (colors.get(v.getTag()).equals("red")) {
          // it is red!
      }
      

    (请注意,这与Biju Parvathy的建议非常接近,但他没有明确说明如何处理按钮颜色/图像的变化。)

    首先
    参考资料。getDrawable(int)
    已被弃用,因此在一些较新的设备中肯定会遇到此类问题。更好的方法是为每个特定按钮使用的可绘制按钮使用标签。例如,考虑你有4个按钮,即Butn1、Butn2、Butn3和Buto4。现在假设首字母都有一些背景

    比方说

    button1.setBackgroundResource(R.drawable.default1);
    button1.setTag(R.drawable.default1); // set the tag for button same as the drawable id
    
    对所有4个按钮执行相同操作

    button4.setBackgroundResource(R.drawable.default4);
    button4.setTag(R.drawable.default4); // set the tag for button same as the drawable id
    
    现在,每当您更改按钮的背景/图像时,您也需要更新标记,如下所示

    button1.setBackgroundResource(R.drawable.redimage);
    button1.setTag(R.drawable.redimage); // set the tag for button same as the drawable id
    
    在按钮
    onClick()
    上,您只需使用开关盒来区分不同的标记

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
            switch(button1.getTag()){
                case R.drawable.default1:
                // do whatever action you want to perform
                break;
                case R.drawable.redimage:
                // do whatever action you want to perform
                break;
            }
            break;
            // similarly you can do the same for rest of the buttons.
        }
    }
    

    希望这对您有所帮助。

    您可以,我正在对您的比较代码进行一个小小的更改,使其适用于所有设备

    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
    }
    
    有关更多详细信息,请参阅函数。
    希望这能对您有所帮助。

    为什么要将点击与背景而不是视图id进行比较?
    为什么这不起作用有时
    不是一个好的问题标题。我仍然不明白为什么我们不能依靠
    位图对象
    进行比较。此外,我只交换图像,而不是实际的按钮,那么如何将
    HashMap
    标记
    附加到绘图页?非常感谢斯蒂芬!您还没有向我们显示相关代码。然而,很明显,在代码中,您没有向我们展示的某些东西正在假设它不应该这样做。例如,javadoc是否保证当您设置一个按钮图像,然后获取它时,您将得到相同的
    位图
    对象?好的,那么如果我们确实假设
    位图
    对象在某种程度上不准确,我如何为每个图像创建一个
    哈希映射
    ,或者为每个按钮创建一个
    标记
    。我喜欢你给我的最后一个选项,让我看地图上的按钮颜色。我该怎么做?但我并没有真正地切换按钮……”“那么我如何将HashMap或标记附加到可绘制的文件上?”-你没有。Hashmap是应用程序状态(模型)的一部分。标记与按钮相关联,而不是与可绘制文件相关联。您不会为每个图像创建HashMap。请再读一遍我的答案。这与我一直在做的有什么不同呢?
    ==
    操作符只检查引用,不会比较位图数据所以你只是说将==更改为=?我的建议是使用
    sameAs()
    函数进行比较,而不是使用
    =
    :)正如我们已经知道的那样,
    SameAs
    将比较数据,其中as
    ==
    比较参考。我怀疑的是,一些设备供应商可能已经在引擎盖下实现了位图缓存,所以一直以来
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
            switch(button1.getTag()){
                case R.drawable.default1:
                // do whatever action you want to perform
                break;
                case R.drawable.redimage:
                // do whatever action you want to perform
                break;
            }
            break;
            // similarly you can do the same for rest of the buttons.
        }
    }
    
    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
    }