Aviv
Aviv

Reputation: 313

creating buttons positioned randomly, without exceeding the screen size

I'm trying to create an Activity that contains 10 buttons that are generated programmatically and are positioned in random places on the screen but without exceed the screen size.

I tried doing so but most of the buttons exceeded from the screen size (I couldn't see it).

    LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear);
    Random rnd = new Random();

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int height = displaymetrics.heightPixels;
    int width = displaymetrics.widthPixels;

    for(int x = 0;x<10;x++) {

        Button btn = new Button(this);

        int Xpoistion = rnd.nextInt(width - 100) + 100;
        int Yposition = rnd.nextInt(height - 100) + 100;

        btn.setX(Xpoistion);
        btn.setY(Yposition);

        btn.setText(x +")"+width + "," + height + " | " + Xpoistion + "," + Yposition);

        linearLayout.addView(btn);

    }

So i'm trying to create the "limits of the screen" from height and width but for some reason I can't figure it out.

I played with Xposition and Yposition a lot but nothing seems to work for me.

Thank for very much for your help.

Upvotes: 3

Views: 137

Answers (2)

Greggz
Greggz

Reputation: 1799

You should use the RelativeLayout as said already. But your logic is a bit flawed, you should set variables to garantee your buttons don't go of screen. I added a bit of code to yours already

    int height = displaymetrics.heightPixels;
    int width = displaymetrics.widthPixels;
    int buttonWidth = 150;
    int buttonHeigh = 40;
    int max_x_val = width - buttonWidth;
    int max_y_val = heigth - buttonHeigh; // Edited here

    for(int x = 0;x<10;x++) {

        Button btn = new Button(this);

        int Xpoistion = rnd.nextInt(max_x_val - buttonWidth) + buttonWidth;
        int Yposition = rnd.nextInt(max_y_val - buttonHeigh) + buttonHeigh;

        btn.setX(Xpoistion);
        btn.setY(Yposition);
        btn.setWidth(buttonWidth);
        btn.setHeight(buttonHeigh);
        btn.setText(x +")"+width + "," + height + " | " + Xpoistion + "," + Yposition);

        relativeLayout.addView(btn);
        Log.d("Debug","Xpos =" + Xpoistion);
        Log.d("Debug","Ypos =" + Yposition);
    }

This still is not the solution because the buttons might end up overlapped

Last edit

There are still some buttons that get a bit cut.This happens because we have the whole dimensions of the screen, and what we needed was the dimensions of only our Relative Layout .. That blue bar on top is also being included in the measure when it shouldn't. But this error is a bit more tricky to fix but not impossible, just google a bit and you will find enough help

EDIT: My initial thought was that btn.setX() and setY() would center the Button on those pixels, but no it marks the start of the button in those same pixels, so I had to change the randomize function to simply:

int Xposition = rnd.nextInt(width - buttonWidth);
int Yposition = rnd.nextInt(height - buttonHeight);

Next, to work around overlapping I wrote the following sample

// Create dummy class for holding coordinates
public class ButtonCordinates{

 public int x;
 public int y;

 public ButtonCordinates(int x, int y) {
     this.x = x;
     this.y = y;
 }
}

//In MainActivity class create a array for holding coordinates
ButtonCoordinates [] buttonsCoordinates = new ButtonCoordinates [10];    

int x = 0;
while(x < 10) {

  int Xposition = rnd.nextInt(width - buttonWidth);
  int Yposition = rnd.nextInt(height - buttonHeight);

  ButtonCoordinates buttonCoords = new ButtonCoordinates (Xposition,Yposition);

  if(!coordinatesFree(buttonCoords,buttonHeight,buttonWidth)){
    // Get another chance
    continue;
  }

  Button btn = new Button(this);
  btn.setX(Xposition);
  btn.setY(Yposition);

  btn.setWidth(buttonWidth);
  btn.setHeight(buttonHeight);
  btn.setText(Xposition+";"+Yposition);

  buttonsCoordinatesArray[x++] = buttonCoords;

  linearLayout.addView(btn);
  Log.d("Debug","Xpos =" + Xposition);
  Log.d("Debug","Ypos =" + Yposition);
}

// Method that prevents overlapping
private boolean coordinatesFree(ButtonCoordinates newButton, int buttonHeight, int buttonWidth){

     for(ButtonCoordinates existingButton : buttonsCoordinatesArray){
        if(existingButton == null){
            // First button ever
            return true;
        }

        boolean f1 = existingButton.x + buttonWidth <= newButton.x;
        boolean f2 = existingButton.y + buttonHeight <= newButton.y;
        boolean f3 = existingButton.x - buttonWidth >= newButton.x;
        boolean f4 = existingButton.y - buttonHeight >= newButton.y;

        if(!f1 && !f2 && !f3 && !f4){
            return false;
        }

    }
    return true;
}

Upvotes: 1

Yuliwee
Yuliwee

Reputation: 337

You need to use RelativeLayout instead of LinearLayout to place your buttons with absolute values.

Edit: I just looked for a reference, you can find it here.

Upvotes: 1

Related Questions