RelativeLayout изменяется во время выполнения - PullRequest
2 голосов
/ 03 июня 2011

У меня есть игра-головоломка, в которой доска представляет собой прямоугольник, а граница состоит из фрагмента длиной в одну единицу сетки. У меня есть метод, который рандомизирует изображения и оборачивает их вокруг уровня, но ... это действительно ужасно. И в этом самая странная ошибка: в зависимости от того, какая версия Android работает, она ведет себя по-разному. На 2.1 границы не выровнены должным образом, когда начинается действие, но они исправляются, как только часть перемещается. Не когда часть движется, а когда она перемещается в другое положение (если бы я перетащил ее по экрану и бросил обратно в то же место, ничего бы не случилось). Когда часть фактически отбрасывается (MotionEvent.ACTION_UP), это когда граница исправляется сама. В 2.2 он запускается правильно, но когда я загружаю новый уровень (который не запускает новое действие, а снова вызывает createBorder), он действует так же. Вот как это выглядит:

enter image description here

Вот мой метод createBorder:

private void createBorder(int h, int w, int levelWidthUnits, int levelHeightUnits){

    //This method could definitely use some work (understatement), but it's all right for the moment.
    //int blankPiece = 0;
    int bored = board.getId();
    int lastBorder = 0;
    int borderWidth = 0;
    Matrix m90 = new Matrix();
    m90.setRotate(90);
    Matrix m180 = new Matrix();
    m180.setRotate(180);
    Matrix m270 = new Matrix();
    m270.setRotate(270);
    Bitmap bm1 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
    borderWidth = (int)(bm1.getHeight()/(bm1.getWidth()/((float)(w/levelWidthUnits))));
    //Log.i(TAG, "borderWidth = "+borderWidth);

    for(int counter=0;counter<levelWidthUnits;counter++){

        Bitmap bm = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
        Bitmap borderbm = Bitmap.createScaledBitmap(bm, (w/levelWidthUnits), borderWidth, true);
        ImageView border = new ImageView(this);
        border.setImageBitmap(borderbm);
        border.setId(0x90000000+counter);
        //border.setImageResource(R.drawable.border_tiki1);
        //border.setAdjustViewBounds(true);
        //border.setImageMatrix(matrixTop);
        //border.setScaleType(ImageView.ScaleType.MATRIX);

        LayoutParams params = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
        if(counter==0){
            params.addRule(RelativeLayout.ALIGN_LEFT, bored);
            params.addRule(RelativeLayout.ABOVE, bored);
        }else{
            //Log.i(TAG, "lastBorder before added rule = "+lastBorder);//TODO Why does this only work for the 3rd through 6th pieces?!
            params.addRule(RelativeLayout.RIGHT_OF, lastBorder);    //This method works just fine for everything but the 2nd piece!
            params.addRule(RelativeLayout.ABOVE, bored);            //And even for the 2nd piece, this line works! Just not the one above.
        }
        border.setLayoutParams(params);
        game_view.addView(border);
        lastBorder = border.getId();
        //Log.i(TAG, "lastBorder set to: "+lastBorder);
    }
    Bitmap cbm = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
    Bitmap cornerbm1 = Bitmap.createScaledBitmap(cbm, borderWidth, borderWidth, true);
    Bitmap cornerbm = Bitmap.createBitmap(cornerbm1, 0, 0, borderWidth, borderWidth, m90, true);
    ImageView border1 = new ImageView(this);
    border1.setImageBitmap(cornerbm);
    border1.setId(lastBorder+1);
    LayoutParams params = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.RIGHT_OF, lastBorder);
    params.addRule(RelativeLayout.ABOVE, bored);
    border1.setLayoutParams(params);
    game_view.addView(border1);
    lastBorder = border1.getId();

    for(int counter=0;counter<levelHeightUnits;counter++){
        Bitmap bm2 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
        Bitmap borderbm2 = Bitmap.createScaledBitmap(bm2, (h/levelHeightUnits), borderWidth, true);
        Bitmap borderbm1 = Bitmap.createBitmap(borderbm2, 0, 0, (h/levelHeightUnits), borderWidth, m90, true);
        ImageView border = new ImageView(this);
        border.setImageBitmap(borderbm1);
        border.setId(lastBorder+1);

        LayoutParams params2 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
        params2.addRule(RelativeLayout.RIGHT_OF, bored);
        params2.addRule(RelativeLayout.BELOW, lastBorder);
        border.setLayoutParams(params2);
        ((ViewGroup) findViewById(R.id.game_view)).addView(border);
        lastBorder = border.getId();
        /*if(counter==2){
            blankPiece = border.getId();
        }*/
        //Log.i(TAG, "lastBorder set to: "+lastBorder);
    }

    Bitmap cbm2 = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
    Bitmap cornerbm21 = Bitmap.createScaledBitmap(cbm2, borderWidth, borderWidth, true);
    Bitmap cornerbm2 = Bitmap.createBitmap(cornerbm21, 0, 0, borderWidth, borderWidth, m180, true);
    ImageView border2 = new ImageView(this);
    border2.setImageBitmap(cornerbm2);
    border2.setId(lastBorder+1);
    LayoutParams params1 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
    params1.addRule(RelativeLayout.ALIGN_LEFT, lastBorder);
    params1.addRule(RelativeLayout.BELOW, lastBorder);
    border2.setLayoutParams(params1);
    ((ViewGroup) findViewById(R.id.game_view)).addView(border2);
    lastBorder = border2.getId();

    for(int counter=0;counter<levelWidthUnits;counter++){
        Bitmap bm2 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
        Bitmap borderbm2 = Bitmap.createScaledBitmap(bm2, (h/levelHeightUnits), borderWidth, true);
        Bitmap borderbm1 = Bitmap.createBitmap(borderbm2, 0, 0, (h/levelHeightUnits), borderWidth, m180, true);
        ImageView border = new ImageView(this);
        border.setImageBitmap(borderbm1);
        border.setId(lastBorder+1);

        LayoutParams params2 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
        params2.addRule(RelativeLayout.ALIGN_TOP, lastBorder);
        params2.addRule(RelativeLayout.LEFT_OF, lastBorder);
        border.setLayoutParams(params2);
        ((ViewGroup) findViewById(R.id.game_view)).addView(border);
        lastBorder = border.getId();
        //Log.i(TAG, "lastBorder set to: "+lastBorder);
    }

    Bitmap cbm3 = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
    Bitmap cornerbm31 = Bitmap.createScaledBitmap(cbm3, borderWidth, borderWidth, true);
    Bitmap cornerbm3 = Bitmap.createBitmap(cornerbm31, 0, 0, borderWidth, borderWidth, m270, true);
    ImageView border3 = new ImageView(this);
    border3.setImageBitmap(cornerbm3);
    border3.setId(lastBorder+1);
    LayoutParams params2 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
    params2.addRule(RelativeLayout.ALIGN_TOP, lastBorder);
    params2.addRule(RelativeLayout.LEFT_OF, lastBorder);
    border3.setLayoutParams(params2);
    ((ViewGroup) findViewById(R.id.game_view)).addView(border3);
    lastBorder = border3.getId();

    for(int counter=0;counter<levelHeightUnits;counter++){
        Bitmap bm2 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
        Bitmap borderbm2 = Bitmap.createScaledBitmap(bm2, (h/levelHeightUnits), borderWidth, true);
        Bitmap borderbm1 = Bitmap.createBitmap(borderbm2, 0, 0, (h/levelHeightUnits), borderWidth, m270, true);
        ImageView border = new ImageView(this);
        border.setImageBitmap(borderbm1);
        border.setId(lastBorder+1);

        LayoutParams params3 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
        params3.addRule(RelativeLayout.LEFT_OF, bored);
        params3.addRule(RelativeLayout.ABOVE, lastBorder);
        border.setLayoutParams(params3);
        ((ViewGroup) findViewById(R.id.game_view)).addView(border);
        lastBorder = border.getId();
        //Log.i(TAG, "lastBorder set to: "+lastBorder);
    }

    Bitmap cbm4 = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
    Bitmap cornerbm41 = Bitmap.createScaledBitmap(cbm4, borderWidth, borderWidth, true);
    Bitmap cornerbm4 = Bitmap.createBitmap(cornerbm41, 0, 0, borderWidth, borderWidth, null, true);
    ImageView border4 = new ImageView(this);
    border4.setImageBitmap(cornerbm4);
    border4.setId(lastBorder+1);
    LayoutParams params3 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
    params3.addRule(RelativeLayout.ALIGN_LEFT, lastBorder);
    params3.addRule(RelativeLayout.ABOVE, lastBorder);
    border4.setLayoutParams(params3);
    ((ViewGroup) findViewById(R.id.game_view)).addView(border4);
    lastBorder = border4.getId();
}

Когда кусок падает, он проверяет, сдвинулся он или нет. Если это так, он вызывает

counter.setText("Total moves: " + moves); //counter is a TextView  

Это то, что, как мне кажется, каким-то образом заставляет компоновку исправляться (возможно, запрашивая перерисовку экрана?). Я ищу исправление к странному сбою, который я получаю, но если у вас есть лучшее предложение о том, как обернуть эти случайные границы, я был бы рад услышать это! (Примечание: в будущем я хочу иметь уровень, который не будет прямоугольником, но все еще будет иметь углы 90 градусов). Спасибо за помощь! Это последняя ошибка, стоящая между мной и выпуском моей игры!

Ответы [ 2 ]

1 голос
/ 03 июня 2011

Я бы согласился с Гангнусом о перерисовке всего в этом случае.

Моя главная причина ответа была: «Если у вас есть лучшее предложение о том, как обернуть эти случайные границы, я бырад слышать это!"часть.Дело не в том, что ваш код настолько плох, но вы правы, что вам понадобится немного поработать, если вы хотите создавать непрямоугольные карты.Вот моя идея для этого, по крайней мере.

Я бы начал с логического уровня «карта», чтобы определить, какие из них являются «бортовыми» и «не бортовыми» квадратами.

В базовой функции прокрутите каждую плитку.Проверьте, есть ли «активная» плитка на каждой стороне.Если это так, вызовите функцию addBorder() с желаемым расположением и поворотом.

void createBorders(int widthUnits, int heightUnits, boolean[][] activeMap) {
    for(int x=0;x<widthUnits;x++) {
        for(int y=0;y<heightUnits;y++) {
            if(!activeMap[x][y])    // boolean "map" (true if active)
                continue;

            if(x == 0)
                addBorder(LEFT, x, y);
            else if(!activeMap[x-1][y])
                addBorder(LEFT, x, y);

            if(x == widthUnits-1)
                addBorder(RIGHT, x, y);
            else if(!activeMap[x+1][y])
                addBorder(RIGHT, x, y);

            if(y == 0)
                addBorder(TOP, x, y);
            else if(!activeMap[x][y-1])
                addBorder(TOP, x, y);

            if(y == heightUnits-1)
                addBorder(BOTTOM, x, y);
            else if(!activeMap[x][y+1])
                addBorder(BOTTOM, x, y);
        }
    }
}

В функции addBorder() получите левое и верхнее расположение плитки, как в (board.left + (tile.width * x)) для левой, аналогично для top.

Затем вы можете switch(where) и повернуть матрицу, изменить размер растрового изображения и при необходимости отрегулировать местоположение от базового местоположения плитки.

Это примерно так, как явсе равно сделал быТаким образом, он работает с любой плиткой на основе карты, даже с внутренней неактивной областью, без жестко закодированных «краев», которые вы используете сейчас.

0 голосов
/ 03 июня 2011

У меня была похожая проблема с представлениями с изображениями bkg в 2.2.В LinearLayout.Единственный способ, которым я знаю, - это принять, что макет по умолчанию не работает правильно, и перерисовать все по коду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...