简体   繁体   中英

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. 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. 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.

The code

BubbleImage XML

This is the layout for an image, the onClickEvent is directly set to the RelativeLayout not the ImageView within the relativelayout

<?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

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):

  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

  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

 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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