0

我正在为纸牌游戏创建一个 Android 应用程序。基本上,我有它,所以屏幕上一次有四行三张卡片,每张卡片由一个可按下的ImageButton. 我的问题是我想使用一个 for 循环,这样我就可OnClickListeners以为这十二张卡片创建,同时有一种方法可以跟踪我们在哪个数字卡片上,这样我就可以正确跟踪按下了哪个按钮。在下面的代码中,我使用计数器来跟踪推送了多少张卡片,并pressed_index跟踪推送了三张卡片。如果计数器不等于 3,我会更改 上的滤色器ImageButton以使其显示为被推动。但是,当我设置匿名类时,我不能使用 x 变量,因为它在匿名类中是不允许的。我需要能够设置pressed_index到当前卡的值,否则我将无法知道12张卡中的哪一张被推送。

ImageButton[] hand = new ImageButton[12];
int[] pressed_index = new int[3];
int counter = 0;
for (int x = 0; x < 12; x++) {
    hand[x] = (ImageButton)findViewById(R.id.//card_1, card_2, etc.);
    hand[x].setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
                pressed_index[counter] = x;
                counter++;
                if (counter != 3) {
                    ((ImageView) v).setColorFilter(Color.argb(150, 155, 155, 155));
                }
            }
    });
}

另一种选择,这就是我现在拥有的方式,并且我能想到的唯一方法是硬编码所有十二种方法并实际输入每个数字。但是,这非常低效,并且使得更新代码变得非常困难。正确设置ID的问题还不错,我只是从x构造的字符串中获取ID,像这样...

int ID = getResources().getIdentifier(("card_"+(x+1)),"id","com.example.project");
hand[x] = (ImageButton)findViewById(ID);

...类似于在此处找到的解决方案:Android:在循环中使用带有字符串 / 的 findViewById() 但是,到目前为止,即使经过大量研究,我也无法解决使用 x 的问题。通过诸如Accessing variables from onclicklistenerAndroid: Accessing a global Variable inside an onClickListener 之类的帖子,似乎只能final传递变量,一个常见的解决方法是创建一个单独的类而不是使用匿名类。然而,这并没有让我走得太远,因为当我开始为 编写单独的类时OnClickListener,我遇到了同样的问题,因为我无法传递变量来创建OnClickListener以将其与正确的卡匹配。如果您对如何解决此问题有任何想法,请告诉我。

4

1 回答 1

3

习语将是常规的 Java/Android

ImageButton[] hand = new ImageButton[12];
int[] pressed_index = new int[3];
int counter = 0;
for (int x = 0; x < 12; x++) {
    final int x_ = x;
    hand[x] = (ImageButton)findViewById(R.id.//card_1, card_2, etc.);
    hand[x].setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
             pressed_index[counter] = x_;
             counter++;
             if (counter != 3) {
                 ((ImageView) v).setColorFilter(Color.argb(150, 155, 155, 155));
             }
        }
    });
}

也就是你引入一个辅助final变量,给它赋值迭代器,然后在匿名内部类中引用final helper;您可能会说您正在以这种方式“捕获”变量。虽然这与您在 lambda 语法中关闭变量的方式非常相似,但将这种显式代码风味sigh归咎于 Java 设计。

或者,请注意,虽然匿名类中使用的变量的引用必须是 final 的,但这并不意味着您不能更改引用的对象;例如

final Foo foo = new Foo();
bar.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            foo.doBaz();
        }
});

是完全有效的代码 - 然后您可以自由更改方法foo中的状态。doBaz()见鬼,你甚至可以(严重的代码气味 - 不要在家里尝试这个!)

ImageButton[] hand = new ImageButton[12];
int[] pressed_index = new int[3];
int counter = 0;
for (int[] x = new int[]{0}; x[0] < 12; x[0]++) {
    hand[x[0]] = (ImageButton)findViewById(R.id.//card_1, card_2, etc.);
    hand[x[0]].setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
                pressed_index[counter] = x[0];
                counter++;
                if (counter != 3) {
                    ((ImageView) v).setColorFilter(Color.argb(150, 155, 155, 155));
                }
        }
    });
}
于 2014-01-18T09:11:21.587 回答