简体   繁体   English

Android位置在2.X上不正确

[英]Android locations not correct on 2.X

I'm going to try and explain the issue as detailed as possible, but since it's a pretty specific issue this is going to be hard. 我将尝试尽可能详细地解释该问题,但是由于这是一个非常具体的问题,因此这将非常困难。 But I'm at the end of my options and really don't have any idea how to fix this. 但是我已经选择不了了,真的不知道如何解决这个问题。

I'm creating an Android game where the users clicks images in the right order to advance to the next level. 我正在创建一个Android游戏,其中用户以正确的顺序单击图像以前进到下一个级别。 I generate these images on random locations on the screen and when a users clicks an image it should fire an event. 我在屏幕上的随机位置生成这些图像,并且当用户单击图像时,它将触发事件。 On Android versions 4.0 and above this works perfectly. 在Android 4.0及更高版本上,此功能非常有效。 However, when I test it on lower versions the locations are of the images seem correct, but when clicking an image it either fires an event for a different image or it doesn't fire one at all. 但是,当我在较低版本上对其进行测试时,图像的位置似乎正确,但是单击图像时,它会触发另一幅图像的事件,或者根本不会触发。 Also when you click an empty space (often around the top left corner) it also fires an event. 另外,当您单击空白区域(通常在左上角附近)时,也会触发一个事件。 I don't know for sure if it's the low Android version or low screen resolution. 我不确定这是Android版本低还是屏幕分辨率低。

The code 编码

BubbleImage XML BubbleImage XML

This is the layout for an image, the onClickEvent is directly set to the RelativeLayout not the ImageView within the relativelayout 这是图像的布局,onClickEvent直接设置为RelativeLayout而不是relativelayout内的ImageView

<?xml version="1.0" encoding="utf-8"?>
<com.timkranen.customui.BubbleImage xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bubImgMain"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<ImageView
    android:id="@+id/bubbleImage"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="fitXY"
    android:adjustViewBounds="true"
    android:src="@drawable/bubble_selector" />

    <TextView
    android:id="@+id/numberTxtView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/bubbleImage"
    android:layout_alignLeft="@+id/bubbleImage"
    android:layout_alignBottom="@+id/bubbleImage"
    android:layout_alignRight="@+id/bubbleImage"
    android:gravity="center"
    android:text="test"
    android:textColor="#fff"
    android:textSize="23sp" />

"

Generating random BubbleImages 生成随机的BubbleImages

Sorry for the long piece code here, I should mention that I use the ninoldandroid library to get the correct x/y coordinates on older Android version (the ViewHelper class does this): 抱歉,这里的代码很长,我应该提一下,我使用ninoldandroid库在较旧的Android版本上获取正确的x / y坐标(ViewHelper类执行此操作):

  private void generateRandomView(int amount) {
    LayoutInflater inflater = (LayoutInflater) this
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    for (int i = 0; i <= amount; i++) {
        // add imageview to layout
        BubbleImage rImg = (BubbleImage) inflater.inflate(
                R.layout.bubbleimage, null);
        rImg.setEnabled(false);
        rImg.setOnClickListener(new BubbleClick());
        bubbleImages.add(rImg);
        totalBubbles++;

        // create random number in between amount and 0
        int genNum = this.generateRandomNum(amount);
        rImg.setNumber(genNum);
        numbers.add(genNum);

        // determine the screen size
        screenSize = getScreenSize();
        screenSize.x = screenSize.x - screenSize.x / 4;
        screenSize.y = screenSize.y - ((screenSize.x / 4) * 3) + 20;

        // stick might throw a stackoverflow error if its called too much
        // but the game only needs to call it on level max
        // stackoverflowerror @ 10x on 300x300
        // stackoverflowerror @ 16x on 250x250
        // depends on screen size
        Point randomLoc = null;
        try {
            Random random = new Random();
            randomLoc = generateRandomLocation(screenSize, random);
        } catch (StackOverflowError e) {
            Toast.makeText(
                    this,
                    "BrainTest PRO encountered a fatal error caused by low memomory on your device. Restart the app and try again, if the error persists please report it to the developer.",
                    Toast.LENGTH_LONG).show();
            finish();
        }

        Resources r = getResources();


        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(180,
                180);
        mainLayout.addView(rImg, params);

        ViewHelper.setTranslationX(rImg, (float) randomLoc.x);
        ViewHelper.setTranslationY(rImg, (float) randomLoc.y);

        // scalefactor on basis of screensize
        float scaleFactor = 1.2f;
        ViewHelper.setScaleX(rImg, scaleFactor);
        ViewHelper.setScaleY(rImg, scaleFactor);

Generate random location method 生成随机定位方法

I don't think I need to clarify generateRandomNum() but I do have to clarify this method, it's a recursive method that goes into a loop until the generated images don't collide anymore 我认为不需要澄清generateRandomNum(),但是我必须澄清这种方法,它是一种递归方法,会循环进入直到生成的图像不再碰撞为止

  private Point generateRandomLocation(Point dimensions, Random random) {

    // generate random x
    int x = random.nextInt((dimensions.x - 0) + 1);

    // generate random y
    int y = random.nextInt((dimensions.y - 0) + 1);

    Point location = new Point(x, y);

    if (!collision(location)) {
        return new Point(x, y);
    } else {
        return generateRandomLocation(dimensions, new Random());
    }

}

BubbleClick event This is the event that fires, the event itself works but it doesn't fire on the right locations BubbleClick事件这是会触发的事件,事件本身可以运行,但不会在正确的位置触发

 private class BubbleClick implements OnClickListener {

    private ScoreCalculator calculator;

    public BubbleClick() {
        calculator = new ScoreCalculator();
    }

    @Override
    public void onClick(View arg0) {
        BubbleImage clicked = (BubbleImage) arg0;
        Log.d("Clicked_bubble", "Num: " + clicked.getNumber() + " | X: " + ViewHelper.getTranslationX(clicked) + " | Y: " + ViewHelper.getTranslationY(clicked));
        ImageView clicked_img = (ImageView) clicked
                .findViewById(R.id.bubbleImage);
        if (currentClick == clicked.getNumber()) {
            if (previousBub != null) {
                GameActivity.this.drawLine(clicked);
            }

            // SUCCESFULL CLICK
            score += calculator.pointsPerBubble(currentLevel);
            scoreLabel.setText("Score: " + String.valueOf(score));
            // clicked_img.setImageResource(R.drawable.bubble_ok);
            clicked.setEnabled(false);
            previousBub = clicked;
            playPosSound();

            for (int i = 0; i <= clicked.getChildCount(); i++) {
                View child = clicked.getChildAt(i);
                if (child instanceof TextView) {
                    TextView txtView = (TextView) clicked.getChildAt(i);
                    txtView.setVisibility(View.VISIBLE);
                }
            }

            // check wether the last bubbleimage was clicked
            if (countListClick + 1 != numbers.size()) {
                countListClick++;
                currentClick = numbers.get(countListClick);
            } else {
                GameActivity.this.resetGame(true);
            }

        } else {
            // WRONG ATTEMPT
            clicked_img.setImageResource(R.drawable.bubble_wrong);
            scores.add(new Score(score, attempt));
            attempt++;
            if (attempt > 3) {
                // GAME OVER
                isGameOver = true;
                continueBut.setVisibility(View.INVISIBLE);
                GameActivity.this.gameOver();
            }

            previousBub = null;

            playNegSound();

            if (currentLevel > 0) {
                currentLevel--;
            }

            vibrate();

            for (int i = 0; i <= clicked.getChildCount(); i++) {
                View child = clicked.getChildAt(i);
                if (child instanceof TextView) {
                    TextView txtView = (TextView) clicked.getChildAt(i);
                    txtView.setVisibility(View.VISIBLE);
                }
            }

            // show all text and disable buttons
            if (bubbleImages != null) {
                for (BubbleImage bImg : bubbleImages) {
                    bImg.setEnabled(false);
                    for (int i = 0; i <= bImg.getChildCount(); i++) {
                        View childV = bImg.getChildAt(i);
                        if (childV instanceof TextView) {
                            TextView childView = (TextView) childV;
                            childView.setVisibility(View.VISIBLE);
                        }
                    }
                }
            }

            if (!isGameOver) {
                GameActivity.this.resetGame(false);
            }

            // GAME OVER

        }

    }

The contents of the onClickListener are pretty irrelevant as the code runs fine just not on the right moments. onClickListener的内容是无关紧要的,因为代码不能在适当的时候正常运行。 Does anyone have any idea what's happening? 有人知道发生了什么吗?

Thanks in advance! 提前致谢!

Because this was a real problem for me: 因为这对我来说是一个真正的问题:

The ViewHelper.getTranslation method does not behave the same on 2.x as it does on 4.x, I used Margins instead. ViewHelper.getTranslation方法在2.x上的行为不同于在4.x上的行为,我改用了Margins。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM