I'm trying to create a chess game board with 8x8 buttons. I'm using nested LinearLayouts. The problem is that there's a padding between each row of ImageViews that I can't get rid of. This is what I have sofar, the board should be square, but isn't:
public class BoardLayout extends LinearLayout {
public BoardLayout(Context context) {
super(context);
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
setLayoutParams(parms);
setOrientation(LinearLayout.VERTICAL);
setPadding(0, 0, 0, 0);
for (int i = 0; i < 8; i++) {
LinearLayout row = new LinearLayout(context);
row.setLayoutParams(parms);
row.setOrientation(LinearLayout.HORIZONTAL);
row.setPadding(0, 0, 0, 0);
for (int j = 0; j < 8; j++) {
ImageView button = new ImageView(context);
button.setLayoutParams(parms);
button.setImageResource(R.drawable.icon);
button.setAdjustViewBounds(true);
button.setPadding(0, 0, 0, 0);
row.addView(button);
}
addView(row);
}
setSquare();
}
public void setSquare() {
int size = Math.min(getWidth(), getHeight());
// setHeight(size); // Not Function, but this is what I need
// setWidth(size); // Not Function, but this is what I need
// also doesn't work
setLayoutParams(new LinearLayout.LayoutParams(size, size, 1.0f));
}
}
Solution:
As suggested TableLayout is better for what I'm trying to do. So the main class should be changed to a TableLayout and the nested LinearLayouts to TableRows.
But that alone didn't fix it, I also had to call the following in TableLayout:
setShrinkAllColumns(true);
setStretchAllColumns(true);
and for each item inserted, I had to also call:
setAdjustViewBounds(true);
TableLayout
Class Overview
A layout that arranges its children
into rows and columns. A TableLayout
consists of a number of TableRow
objects, each defining a row
(actually, you can have other
children, which will be explained
below). TableLayout containers do not
display border lines for their rows,
columns, or cells.
You are better off using a GridView or TableLayout instead of nested LinearLayouts, since that's what they're designed for.
Related
I'm trying to learn how to write Android programs, and I'm having trouble figuring out how padding works, in particular in a FrameLayout within a TableLayout.
private void fillTable(int nrows, int ncols) {
final int CENTER = 0x11; // used for "gravity" parameters
TableLayout table = (TableLayout) this.findViewById(R.id.tablelayout);
int counter = 1;
TextView text;
for (int i = 0; i < nrows; i++) {
TableRow row = new TableRow(this);
table.addView(row);
for (int j = 0; j < ncols; j++) {
View cell;
text = new TextView(this);
text.setTextColor(Color.BLUE);
text.setText(Integer.toString(counter++));
text.setGravity(CENTER);
if (i == 2 && j == 2) {
FrameLayout frame = new FrameLayout(this);
text.setLayoutParams(new FrameLayout.LayoutParams(90, 45, CENTER));
frame.setPadding(0, 0, 0, 0);
frame.addView(text);
cell = frame;
} else {
cell = text;
}
cell.setBackgroundColor((i + j) % 2 == 0 ? Color.YELLOW : Color.WHITE);
row.addView(cell);
cell.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1F/ncols));
}
row.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1F/nrows));
}
}
tablelayout just looks like this:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tablelayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</TableLayout>
I'm calling this with nrows=12 and ncols=5. I'm running on an emulator whose width is 720 pixels. If I change if (i==2&&j==2) to if (false), so that only an array of TextView is displayed, the columns are even, as I expect. However, with the code as written, the middle column is wider than the others.
I've also tried this adding android:stretchColumns="*" to the tablelayout definition and removing the weight parameter from cell.setLayoutParams, and the results are the same.
Assuming I have a reason to want to specify pixels for text.setLayoutParams (because of what I plan to do later), how would I get the column widths to be the same? Since 90*5 is well under 720, I don't understand why, or where, the extra width is being added.
Whenever you are dealing with weights, you must let the option take care of the remaining space. In this case width. Just set the width of each element to 0:
cell.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.MATCH_PARENT, 1F/ncols));
I have tablelayout with rows and in each row a bunch of textviews (all added programatically, no xml), I want to have gridlines so I am trying to add margins through laoyoutparams but it looks like TableLayout.LayoutParams doesn't apply to textviews only to rows so I am getting a margin on the rows but not on the cells. I have also tried using RelativeLaout.LayoutParams on the cells but thaqt is not working also. Anyone can propose any solution for my problem?
You should use correct LayoutParams for views.
While adding a view to:
TableLayout; use TableLayout.LayoutParams
TableRow; use TableRow.LayoutParams.
Edit: I've edited the code. You want some black spaces for some cells. You can achive this with setting same bg color to that views(or transparent bg for row and views on cell). I think setting same bg color to textViews with tableLayout is easier.
Here is a complete code sample that you can try(colors are added to see output easily):
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TableLayout tableLayout = createTableLayout(16, 14);
setContentView(tableLayout);
makeCellEmpty(tableLayout, 1, 6);
makeCellEmpty(tableLayout, 2, 3);
makeCellEmpty(tableLayout, 3, 8);
makeCellEmpty(tableLayout, 3, 2);
makeCellEmpty(tableLayout, 4, 8);
makeCellEmpty(tableLayout, 6, 9);
}
public void makeCellEmpty(TableLayout tableLayout, int rowIndex, int columnIndex) {
// get row from table with rowIndex
TableRow tableRow = (TableRow) tableLayout.getChildAt(rowIndex);
// get cell from row with columnIndex
TextView textView = (TextView)tableRow.getChildAt(columnIndex);
// make it black
textView.setBackgroundColor(Color.BLACK);
}
private TableLayout createTableLayout(int rowCount, int columnCount) {
// 1) Create a tableLayout and its params
TableLayout.LayoutParams tableLayoutParams = new TableLayout.LayoutParams();
TableLayout tableLayout = new TableLayout(this);
tableLayout.setBackgroundColor(Color.BLACK);
// 2) create tableRow params
TableRow.LayoutParams tableRowParams = new TableRow.LayoutParams();
tableRowParams.setMargins(1, 1, 1, 1);
tableRowParams.weight = 1;
for (int i = 0; i < rowCount; i++) {
// 3) create tableRow
TableRow tableRow = new TableRow(this);
tableRow.setBackgroundColor(Color.BLACK);
for (int j= 0; j < columnCount; j++) {
// 4) create textView
TextView textView = new TextView(this);
textView.setText(String.valueOf(j));
textView.setBackgroundColor(Color.WHITE);
textView.setGravity(Gravity.CENTER);
// 5) add textView to tableRow
tableRow.addView(textView, tableRowParams);
}
// 6) add tableRow to tableLayout
tableLayout.addView(tableRow, tableLayoutParams);
}
return tableLayout;
}
And here is the output for this code that we can see margins are applied correctly:
I am using a TableLayout to print nine pictures. For some reason, I am getting a big gap between rows as shown in the image below. I set the background to green so the gaps are easy to see. My TableLayout is created programmatically. How do I fix this problem so that the gap between rows is not so big?
I have already tried tableRowParams.setMargins(0,0,0,0).
BTW: No I don't want to use ListView, etc.
I have been messing around with the code a lot trying to fix the problem. Below is simply the current state of the code:
EDIT: CORRECT IMAGE:
EDIT: the code now will work fine (thanks to #Guian):
public class FacialExpressionImagesTable extends TableLayout {
public FacialExpressionImagesTable(Context context, List<Bitmap> imageList, int sideDimension, int tableWidth, int tableHeight) {
super(context);
setLayoutParams(new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
setBackgroundColor(Color.BLUE);
setContent(imageList, context, sideDimension);
}
private void setContent(List<Bitmap> imageList, Context context, final int sideDimension) {
final int iHeight = imageList.get(0).getHeight();
final int iWidth = imageList.get(0).getWidth();
int ndx = 0;
for (int r = 0; r < sideDimension; r++) {
TableRow tableRow = new TableRow(context);
TableLayout.LayoutParams forRow = new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
tableRow.setLayoutParams(forRow);
tableRow.setBackgroundColor(Color.RED);
TableRow.LayoutParams elementLayout = new TableRow.LayoutParams(iWidth, LayoutParams.WRAP_CONTENT, 1);
tableRow.requestLayout();
for (int c = 0; c < sideDimension; c++) {
ImageView element = new ImageView(context);
element.setLayoutParams(elementLayout);
element.setAdjustViewBounds(true);
element.setPadding(0, 0, 3, 3);
element.setBackgroundColor(Color.GREEN);
element.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
element.setImageBitmap(imageList.get(ndx++));
element.requestLayout();
tableRow.addView(element);
}
addView(tableRow);
}
}
}
first : be aware that you exchange width and height in :
new TableRow.LayoutParams(iHeight, iWidth);
But anyway, you can't give your table itesm the size of the bitmap's getHeight and getWidth since they will be resized ( depending on the screen size, screen density etc ... you would have to compute the new size according to density... )
here I think they are reduced. that's why the height of the row is too big.
set your layout params so the element take wrap_content in height and 0dip with a layout_weight to 1 in width;
TableRow.LayoutParams elementLayout = new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1 );
then the table row take wrap content as height :
TableLayout.LayoutParams forRow = new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
if image are not scaled as needed, you'll may have to set a scale type to your ImageViews : ( using setScaleType )
elementLayout.setScaleType(ScaleType.CENTER_INSIDE); // or
FIT_CENTER... not quite sure
It should be good, tell if its not.
hope that helps.
Also try setting padding to 0 so that there is no padding inside each row of your table
I want to show a list of flights on a listview. And I want to have them all of them align. I have used a LinearLayout, with gravity and padding. But I want to reduce the space for the 4th column, so then I can do bigger the size of the text. I have tried to set the layout_weight of this element to 0 and all of the rest to 1. But it doesnt work. So far I have this
Any ideas?
If you are going to use ListView with a list of LinearLayout view's (I would go with a TableRow list put into a TableLayout), then I would suggest predefining the width of each column in percentage of the total space (i.e. how much of the screen would you allow the column to allocate). Something among the lines:
// basically you build your adapter here
LinearLayout.LayoutParams wrapWrapLinearLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int[] columnWidths = new int[]{20, 20, 20, 20, 20};
ArrayList<LinearLayout> tableRows = new ArrayList<LinearLayout>();//this is the adapter
LinearLayout row = new LinearLayout(this);
//add a header
row.setLayoutParams(wrapWrapLinearLayoutParams);
row.setGravity(Gravity.CENTER);
row.setBackgroundColor(headerColor);
row.addView(makeTableRowWithText(headerForCol1, columnWidths[0]));
row.addView(makeTableRowWithText(headerForCol2, columnWidths[1]));
row.addView(makeTableRowWithText(headerForCol3, columnWidths[2]));
row.addView(makeTableRowWithText(headerForCol4, columnWidths[3]));
row.addView(makeTableRowWithText(headerForCol5, columnWidths[4]));
tableRows.add(row);
for(int i = 0; i < numberOfItemsInTheFlightsTable; i++) {
row = new LinearLayout(this);
row.setLayoutParams(wrapWrapLinearLayoutParams);
row.setGravity(Gravity.CENTER);
row.addView(makeTableRowWithText(col1Text, columnWidths[0]));
row.addView(makeTableRowWithText(col2Text, columnWidths[1]));
row.addView(makeTableRowWithText(col3Text, columnWidths[2]));
row.addView(makeTableRowWithText(col4Text, columnWidths[3]));
row.addView(makeTableRowWithText(col5Text, columnWidths[4]));
tableRows.add(row);
}
//util method
private TextView recyclableTextView;
public TextView makeTableRowWithText(String text, int widthInPercentOfScreenWidth) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
recyclableTextView = new TextView(this);
recyclableTextView.setText(text);
recyclableTextView.setTextColor(Color.BLACK);
recyclableTextView.setTextSize(20);
recyclableTextView.setWidth(widthInPercentOfScreenWidth * screenWidth / 100);
return recyclableTextView;
}
I mean, the trick is that you predefine the percentage of screen allocated by each column.
Do the following
LinearLayout LL1 containing the first 4 columns
LinearLayout LL2 containing the last column
RelativeLayout RL contains LL1 and LL2
You can now position LL2 to the right of the container
EDITED
Im implementing tablelayout dynamically code below.
private void showCowsTblField() {
for (int row = 0; row < numberOfRowsInField - 1; row++) {
TableRow tableRow = new TableRow(this);
tableRow.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
for (int column = 0; column < numberOfColumnsInField - 1; column++) {
LayoutParams layoutParams = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (column == 0) {
textSno[row][column].setLayoutParams(layoutParams);
layoutParams.setMargins(0, 0, 0, 0);
tableRow.addView(textSno[row][column]);
} else {
blocks[row][column].setLayoutParams(layoutParams);
layoutParams.setMargins(1, 1, 1, 1);
tableRow.addView(blocks[row][column]);
}
tableRow.setBackgroundResource(R.drawable.bar_1);
}
tblCows.addView(tableRow, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
}
here block is a class extends Button class,
in this class iam setting background image as
this.setBackgroundResource(R.drawable.edit_button);
Here problem is the button background image size(height) is changing to fit to tablerow height. which is not looking good.
How i can set button background image to actual size (wrapcontent) in table row.
Please let me know....
Thanks.........
See if that helps - http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
You can set it only if you use http://developer.android.com/reference/android/widget/ImageButton.html
Your code must look something like this:
class MyButton extends ImageButton{...}
this.setScaleType(scaleType);
I tried the following code in my class; which extends button class
this.setMaxHeight(26);
this.setMaxWidth(54);
solved issue.:)