I am making an app where i need to display a seat layout containing 900 to 1200 seats. I had managed to generate a 900 seat layout by creating LinearLayouts with customized TextViews programatically by looping. But I'm pretty sure that is definitely not the way to do it.
Here is what I was doing:
// Seat Layout
LinearLayout linearLayoutSeatContainer;
static final LinearLayout[] rows = new LinearLayout[30];
static final TextView[][] seats = new TextView[30][30];
static final View[][] spaceVertical = new View[30][4];
static final View[] spaceHorizontal = new View[4];
// Populating the screen with seats
for (int i = 0; i < 30; i++) {
rows[i] = new LinearLayout(this);
rows[i].setOrientation(LinearLayout.HORIZONTAL);
// Each loop creates a row of seats
for (int j = 0; j < 30; j++) {
// To add horizontal space after every 10 seats
if (j % 10 == 0) {
spaceVertical[i][(j / 10)] = new View(this);
spaceVertical[i][(j / 10)].setLayoutParams(spaceVerticalParams);
rows[i].addView(spaceVertical[i][(j / 10)]);
}
seats[i][j] = new TextView(this);
seats[i][j].setId(i * 100 + j);
seats[i][j].setLayoutParams(textViewParams);
seats[i][j].setBackgroundResource(R.drawable.seat_circle_empty);
seats[i][j].setClickable(true);
seats[i][j].setOnClickListener(this);
// TODO: Delete randomized code for disabled seats
Random rand = new Random();
int num = rand.nextInt(20);
if (num % 5 == 0 && (i != 0 && j != 0))
seats[i][j].setEnabled(false);
rows[i].addView(seats[i][j]);
}
// Adding the last vertical space between screen and the last seat
spaceVertical[i][3] = new View(this);
spaceVertical[i][3].setLayoutParams(spaceVerticalParams);
rows[i].addView(spaceVertical[i][3]);
// To add horizontal space after every 10 rows of seats
if (i % 10 == 0) {
spaceHorizontal[i / 10] = new View(this);
spaceHorizontal[i / 10].setLayoutParams(spaceHorizontalParams);
linearLayoutSeatContainer.addView(spaceHorizontal[i / 10]);
}
linearLayoutSeatContainer.addView(rows[i]);
}
// Adding the last horizontal space between screen and the last row
spaceHorizontal[3] = new View(this);
spaceHorizontal[3].setLayoutParams(spaceHorizontalParams);
linearLayoutSeatContainer.addView(spaceHorizontal[3]);
Please ignore that bit with the randomization, that was for testing purposes. I know this is not the way of doing things. Please point me towards the right direction.
Related
I have a requirement to display a question along with a list of options that i am getting from server. Each option has a title and an image and these options should be clickable. So I am creating a class ImageButton extending to RelativeLayout and each option is an ImageButton. I am also creating a class ImageButtonGroup extending to GridLayout and dynamimcally adding all the ImageButtons to this ImageButtonGroup.
It works fine except for the alignment of the ImageButtons. The ImageButton's size depends on the length of the title text (the image is of same size for all options) and I am having hard time in distributing equal cell space to each ImageButton in the grid layout. See below my code where I am adding ImageButtons to ImageButtonGroup:
ImageButtonGroup imageButtonGroup =
(ImageButtonGroup)
mInflater.inflate(
R.layout.button_image_response_layout, holder.richTextContainer, false);
int total = item.getMessage().getResponseOptions().size();
int col = 3;
int row = total / col;
imageButtonGroup.setColumnCount(col);
imageButtonGroup.setRowCount(row + 1);
for (int i = 0; i < total; i++) {
ResponseOption responseOption = item.getMessage().getResponseOptions().get(i);
ImageButtonView imageButtonView =
(ImageButtonView)
mInflater.inflate(
R.layout.image_button_layout, holder.richTextContainer, false);
imageButtonView.setData(
responseOption.getImage(), responseOption.getViewText(), responseOption.getValue());
GridLayout.LayoutParams gridParam = new GridLayout.LayoutParams();
gridParam.setGravity(Gravity.CENTER);
gridParam.topMargin = 10;
gridParam.bottomMargin = 10;
gridParam.width = GridLayout.LayoutParams.WRAP_CONTENT;
gridParam.height = GridLayout.LayoutParams.WRAP_CONTENT;
imageButtonGroup.addView(imageButtonView, gridParam);
This gets me the following view:(The text isn't always Happy as shown below)
How to dynamically allocate fixed sized cell to these buttons inside a grid layout?
You can to specify row and column while creating the GridLayoutParams so that it will handle itself the matching of the size dependending on the total space:
GridLayout.LayoutParams first = new GridLayout.LayoutParams(row, col);
GridLayout.LayoutParams(GridLayout.Spec rowSpec, GridLayout.Spec
columnSpec)
Constructs a new LayoutParams instance for this rowSpec and
columnSpec.
In your specific case it will be something like :
for (int i = 0; i < total; i++) {
ResponseOption responseOption = item.getMessage().getResponseOptions().get(i);
ImageButtonView imageButtonView =
(ImageButtonView)
mInflater.inflate(
R.layout.image_button_layout, holder.richTextContainer, false);
imageButtonView.setData(
responseOption.getImage(), responseOption.getViewText(), responseOption.getValue());
Spec row = GridLayout.spec(Math.round(i / 3);
Spec col = GridLayout.spec(i % 3);
GridLayout.LayoutParams gridParam = new GridLayout.LayoutParams(row, col);
gridParam.setGravity(Gravity.CENTER);
gridParam.topMargin = 10;
gridParam.bottomMargin = 10;
gridParam.width = GridLayout.LayoutParams.WRAP_CONTENT;
gridParam.height = GridLayout.LayoutParams.WRAP_CONTENT;
imageButtonGroup.addView(imageButtonView, gridParam);
I was able to achieve this taking a hint from here
I got the screen width, calculated my layout size in terms of %age point (came out to be 70% of the total width) and divided it by 3 (the number of column). So basically what i did is:
int dWidth = (int)(presenter.getView().getScreenWidth() * .70) / 3;
gridParam.width = dWidth;
I recently started making a chess-like game for android. The first thing I needed was to make the 8 by 8 board. I figured adding 64 buttons and organizing them in the XML wouldn't be much efficient, so I found a way to create them programmatically using a simple 8x8 matrix of buttons. Until this point, everything worked as intended, and I had this:
The next thing I tried was to change the colors of the buttons to match a chessboard. On the internet I found some ways of doing it, but pretty much all of them just made my buttons invisible, and did not change their color.
Here's the onCreate method (the only thing I modified so far):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
//GETTING SCREEN DIMENSIONS
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
//SETTING THE BOARD
int TILESIZE = width/8;
LinearLayout back = (LinearLayout) findViewById(R.id.back);
LinearLayout[] rows = new LinearLayout[8];
Button[][] tiles = new Button[8][8];
for(int i = 0; i < 8; i++){
rows[i] = new LinearLayout(this);
back.addView(rows[i]);
for(int j = 0; j < 8; j++){
tiles[i][j] = new Button(this);
tiles[i][j].setWidth(TILESIZE);
tiles[i][j].setHeight(tiles[i][j].getWidth());
if((i + j) % 2 == 0){
tiles[i][j].setBackgroundColor(0xFFFFFFFF);
tiles[i][j].invalidate();
}
else{
//TODO: Make tiles black
}
rows[i].addView(tiles[i][j]);
}
}
}
The XML file contains a single vertical linear layout called back.
My question is how can I make the buttons change color, and where am I doing something wrong. I would also gladly accept alternative (or better) ways to make the board.
Change your loop like this and try
for(int i = 0; i < 8; i++){
rows[i] = new LinearLayout(this);
for(int j = 0; j < 8; j++){
tiles[i][j] = new Button(this);
tiles[i][j].setWidth(TILESIZE);
tiles[i][j].setHeight(tiles[i][j].getWidth());
if((i + j) % 2 == 0){
tiles[i][j].setBackgroundColor(0xFFFFFFFF);
tiles[i][j].invalidate();
}
else{
//TODO: Make tiles black
}
rows[i].addView(tiles[i][j]);
}
back.addView(rows[i]);
}
Change your if loop like this:
if((i + j) % 2 == 0)
tiles[i][j].setBackgroundColor(android.R.color.holo_blue_dark);
else
tiles[i][j].setBackgroundColor(android.R.color.holo_red_dark);
You can define black and white colors in your color.xml file and add them instead using tiles[i][j].setBackgroundColor(getResources().getColor(R.color.white)); and similarly for black.
But make sure, you use a different background so they are clearly visible.
So I'm trying to create a GridView style layout in Android without actually using a custom Gridview adapter, since I don't want it to scroll. I've tried just turning scrolling off, but it ruins my layout since I'm adding other elements around it in a vertical LinearLayout.
My next experiment was to use a TableLayout and then just add inflated layouts as table cells, but I'm also having an issue with this. Here is a test that I am running for a brief proof of concept:
TableRow trackingActivityRow = new TableRow(getActivity());
for(int j = 0; j < trackingActivities.size(); j ++) {
TrackingActivity trackingActivity = trackingActivities.get(j);
View trackingActivityCell = getActivity().getLayoutInflater()
.inflate(R.layout.table_cell_tracking_activity, trackingActivityRow, true);
TextView txtDescription = (TextView)trackingActivityCell.findViewById(R.id.txtDescription);
txtDescription.setText(trackingActivity.getDescription());
}
tableLayout.addView(trackingActivityRow);
It seems to create the number of cells correctly, but it doesn't want to set the text like it should be. Furthermore, I'm having an issue of logic when it comes to creating a new row for every 4 TrackingActivities.
If anyone has any input it would be appreciated.
/Update/
Here is a graphic of the issue. The cell with "Walk" in it is displaying correctly, but the other cells only display the placeholder text inside the textview which should have been replaced.
I created a customized GridView based on a tablelayout with a listadapter.
Simplified version of the setAdapterMethod in the extended TableLayout:
int itemPos = -1;
int numRows = (int) Math.ceil((double) adapter.getCount() / (double) mNumColumns);
for (int yPos = 0; yPos < numRows; yPos++) {
//Create new row
TableRow tableRow = new TableRow(this.getContext());
for (int xPos = 0; xPos < mNumColumns; xPos++) {
itemPos++;
View itemView = adapter.getView(itemPos, null, tableRow);
tableRow.addView(itemView);
}
this.addView(tableRow, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT));
}
I’ve been trying to create a minesweeper game in android, and so far, all has gone accordingly. However, I’m currently stuck on the part where I have to randomly place the mines within the game board.
I’ve tried a few things that I could think of, but none of which worked, except one. However, it doesn’t give me the results that I want. Here is how I am drawing the game board (using a 2D array of buttons).
final Button currentButton = new Button(this);
final int bombState = R.drawable.bomb_state;
final Button[][] buttonArray = new Button[6][6];
final int mine = R.drawable.bomb;
final Random rand = new Random();
final int number = 36;
int button;
int row;
//create new Linear Layout
RelativeLayout linearLayout = new RelativeLayout(this);
//creating the layout Params
LayoutParams linLayoutParam = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
//set layout background
linearLayout.setBackgroundDrawable(getWallpaper());
//set LinearLayout as a root element of the screen
setContentView(linearLayout, linLayoutParam);
//create a new Table Layout for the game grid
TableLayout mineGrid = new TableLayout(this);
/*
* creates TableRows and Buttons using the for loop
* then add the buttons into the rows and the rows
* into the TableLayout
*/
for(row = 0; row < 6; row++){
//create new Table Row
TableRow currentRow = new TableRow(this);
for(button = 0; button < 6; button++){
//create new Button
for(int id = 0; id < number; id++){
currentButton.setId(id);
}
currentButton.setText(" ");
//storing the buttons into the array of Buttons
buttonArray[row][button] = currentButton;
if(currentButton.isClickable()){
currentButton.setOnClickListener(new OnClickListener() {
/*
* (non-Javadoc)
* #see android.view.View.OnClickListener#onClick(android.view.View)
*/
public void onClick(View v) {
try
{
for(int i = 0; i < 10; i++){
if(rand.nextInt(10) == i){
currentButton.setBackgroundResource(mine);
restart.setBackgroundResource(bombState);
}
}
} catch(Exception e)
{
Toast.makeText(Game.this,e.getMessage() + "Error : ",
Toast.LENGTH_SHORT).show();
}
}
});
}
//store the button into the Table Row
currentRow.addView(currentButton);
}
//add the newly created row into the table
mineGrid.addView(currentRow);
}
linearLayout.addView(score, params3);
linearLayout.addView(mineGrid, params);
}
What the above code gives me, is a 6x6 grid made up of buttons.
And the following is where I’m trying to randomly place n amount of mines within the board.
try
{
for(int i = 0; i < 10; i++){
if(rand.nextInt(10) == i){
currentButton.setBackgroundResource(mine);
restart.setBackgroundResource(bombState);
}
}
}
Unfortunately, this fills the whole board with mines, instead of only placing n amount of mine on the board. I know am missing something when I try to randomly set the mines! Can anyone advise me as to where I’m going wrong and help point me in the right direction?
Please ask me anything for clarification.
Thanks in advance.
You basically, on every click of a button try to place a mine instead placing them when you create buttons. Maybe You could add to a list, id of a buttons which are mines and only check if user has clicked on one of those buttons.
ArrayList<Integer> mines = new ArrayList<Integer>();
.
.
.
currentButton.setText(" ");
if(rand.nextInt(2)==1)
mines.add(currentButton.id);
and in onClick() You check if currentButton.id is in mines list and if it is, display appropriate image.
This question already has answers here:
GridLayout (not GridView) how to stretch all children evenly
(25 answers)
Closed 7 months ago.
I made an error in another class, that's why it didn't work. The code below seems to be correct
I'm trying to create a dynamic GridLayout. Inside another class, not this one, I have a method that designs rows and cols of my gridlayout. In the class below, i add some buttons to my GridLayout:
int buttons= 6;//the number of bottons i have to put in GridLayout
int buttonsForEveryRow = 3; // buttons i can put inside every single row
int buttonsForEveryRowAlreadyAddedInTheRow =0; // count the buttons added in a single rows
int columnIndex=0; //cols index to which i add the button
int rowIndex=0; //row index to which i add the button
for(int i=0; i < buttons;i++){
/*if numeroBottoniPerRigaInseriti equals numeroBottoniPerRiga i have to put the other buttons in a new row*/
if(buttonsForEveryRowAlreadyAddedInTheRow ==buttonsForEveryRow ){
rowIndex++; //here i increase the row index
buttonsForEveryRowAlreadyAddedInTheRow =0;
columnIndex=0;
}
Spec row = GridLayout.spec(rowIndex, 1);
Spec colspan = GridLayout.spec(columnIndex, 1);
GridLayout.LayoutParams gridLayoutParam = new GridLayout.LayoutParams(row, colspan);
gridLayout.addView(button_to_add,gridLayoutParam);
buttonsForEveryRowAlreadyAddedInTheRow ++;
columnIndex++;
In the following image you can see what i get: Buttons 3 and 6 are missing. I'm afraid I am not using GridLayout.spec properly.
Using below code you can add image views to grid layout dynamically with column span and row span.
gridLayout = (GridLayout) findViewById(R.id.gridview);
gridLayout.removeAllViews();
int total = 10;
int column = 3;
int row = total / column;
gridLayout.setColumnCount(column);
gridLayout.setRowCount(row + 1);
for (int i = 0, c = 0, r = 0; i < total; i++, c++) {
if (c == column) {
c = 0;
r++;
}
ImageView oImageView = new ImageView(this);
oImageView.setImageResource(R.drawable.ic_launcher);
oImageView.setLayoutParams(new LayoutParams(100, 100));
Spec rowSpan = GridLayout.spec(GridLayout.UNDEFINED, 1);
Spec colspan = GridLayout.spec(GridLayout.UNDEFINED, 1);
if (r == 0 && c == 0) {
Log.e("", "spec");
colspan = GridLayout.spec(GridLayout.UNDEFINED, 2);
rowSpan = GridLayout.spec(GridLayout.UNDEFINED, 2);
}
GridLayout.LayoutParams gridParam = new GridLayout.LayoutParams(
rowSpan, colspan);
gridLayout.addView(oImageView, gridParam);
}