For example I create 4 tablerows programatically and I want each tablerow height to be 1/4 size of the screen. Each tablerow height is half the screen size. I tried different ways, but tablerow height didn't change. I manage change tablerow width, but height doesn't.
Here is my code :
#SuppressLint("NewApi")
public class GameActivity extends Activity {
private Context context;
public void drawTable(){
int i;
TableLayout table = new TableLayout(context);
table.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT));
//table.setStretchAllColumns(true);
//table.setShrinkAllColumns(true);
//table.setWeightSum(1.0F);
TableRow[] rows = new TableRow[5];
for(i = 0; i < 4; ++i){
rows[i] = new TableRow(context);
rows[i].setBackgroundResource(R.drawable.images214);
rows[i].setWeightSum((float)1.0);
rows[i].setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 10));
//rows[i].setScaleY(0.25F);
table.addView(rows[i]);
}
LinearLayout l = (LinearLayout) findViewById(R.id.linear);
l.addView(table);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
context = this;
// TableLayout table = new TableLayout(this);
// TableRow row1 = new TableRow(this);
// TableRow row2 = new TableRow(this);
// row1.addView(new EditText(this));
// row2.addView(new Button(this));
// table.addView(row1);
// table.addView(row2);
// //table.setBackground(getResources().getDrawable(R.drawable.ic_launcher));
// table.setBackgroundResource(R.drawable.ic_launcher);
// LinearLayout l = (LinearLayout) findViewById(R.id.linear);
// l.addView(table);
drawTable();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_game, menu);
return true;
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none"
android:layout_weight="1">
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical|horizontal">
</LinearLayout>
</ScrollView>
</RelativeLayout>
You're not using the proper LayoutParams, for the table TableLayoutyou should set LinearLayout.LayoutParams(as you add the table to a LinearLayout) and for your TableRows the LayoutParams should be TableLayout.LayoutParams(as they are children of TableLayout). Even with the above changes things will not work because the TableLayout is a widget that imposes constraints on its children, most notable the height will be automatically set to WRAP_CONTENT for TableRows. The only way to change this is to use weight like this:
TableLayout table = new TableLayout(context);
table.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
table.setWeightSum(1.0f);
TableRow[] rows = new TableRow[4];
for(int i = 0; i < 4; ++i){
rows[i] = new TableRow(context);
rows[i].setBackgroundResource(R.drawable.images214);
rows[i].setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, 0, 0.25f));
table.addView(rows[i]);
}
LinearLayout l = (LinearLayout) findViewById(R.id.linear);
l.addView(table);
But this will not work, because your TableLayout is set to fill the parent, parent which is a ScrollView which doesn't imposes dimensions on its child. I don't know what you're trying to do with that ScrollView there(especially as you want the table to fill the entire screen) so I don't know what to recommend you. Also, I don't know your full layout but your nesting to many layouts.
For each table row set height:
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int height = metrics.heightPixels / 4; // quarter of screen height
rows[i].setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, height));
Related
I need to create buttons dynamically to a linear layout. The width of each button will be wrap_content. Once the whole row is full, the button should be created in the next row.
I have seen other answers in stackOverflow where this is done, but in those cases the no of buttons in a row is constant. In my case it is dynamic, because the width of each button is dynamic based on text width.
It is similar to how tags are added to a question in this site.
e.g. the answers in one of questions was:
LinearLayout layout = (LinearLayout) findViewById(R.id.linear_layout_tags);
layout.setOrientation(LinearLayout.VERTICAL); //Can also be done in xml by android:orientation="vertical"
for (int i = 0; i < 3; i++) {
LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 4; j++) {
Button btnTag = new Button(this);
btnTag.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
btnTag.setText("Button " + (j + 1 + (i * 4));
btnTag.setId(j + 1 + (i * 4));
row.addView(btnTag);
}
layout.addView(row);
}
But here the no of buttons in a row is constant. In my case , this will be different because the width of each button is different.
You need a FlowLayout, which is an Extended linear layout that wrap its content when there is no place in the current line.
Check this out: https://github.com/ApmeM/android-flowlayout
Have you tried using GridLayout ?
linearLayoutParent = findViewById(R.id.ll_buttons_parent); // container layout or parent layout - orientation vertical
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.button_horizontal_layout, linearLayoutParent, false);
LinearLayout linearLayoutButton = view.findViewById(R.id.ll_button_horizontal);
int rows = 3;
for (int r = 0; r < rows; r++) {
GridLayout gridLayout = new GridLayout(this);
gridLayout.setColumnCount(2);
for (int i = 0; i < 4; i++) {
Button optionButton = new Button(this);
optionButton.setGravity(Gravity.CENTER);
optionButton.setText(String.valueOf(i + 1));
gridLayout.addView(optionButton); // adding buttons to grid layout
}
linearLayoutButton.addView(gridLayout); // adding grid layout to vertical linear layout row by row
}
linearLayoutParent.addView(linearLayoutButton); //adding linear layouts to container layout
Container : ll_buttons_parent
<LinearLayout
android:id="#+id/ll_buttons_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"/>
button_horizontal_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/ll_button_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#F8CCCC"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintTop_toTopOf="parent" />
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 have the following LinearLayout, into which I want to insert a number of dynamically generated TableLayouts. This runs without any errors but nothing is appearing on the screen. Why aren't the TableLayouts appearing? How can I generate the TableLayouts and add them to the LinearLayout?
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/lblOverviewText">
</LinearLayout>
This is how I'm generating the TableLayouts:
var linearLayout = FindViewById<LinearLayout>(Resource.Id.linearLayout2);
foreach (var block in status.blocks)
{
var tableParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.FillParent, TableLayout.LayoutParams.FillParent);
var rowParams = new TableLayout.LayoutParams(TableRow.LayoutParams.FillParent, TableRow.LayoutParams.WrapContent);
var tableLayout = new TableLayout(this);
tableLayout.LayoutParameters = tableParams;
TableRow tableRow = new TableRow(this);
tableRow.LayoutParameters =tableParams;
TextView textView = new TextView(this);
textView.Text = block.Name;
textView.LayoutParameters = rowParams;
tableRow.AddView(textView);
tableLayout.AddView(tableRow, rowParams);
linearLayout.AddView(tableLayout);
}
To start I would delete the alignParentLeft/alignParentRight in the xml for the linearlayout and simply put android:layout_width="match_parent".
You will also need to define the 'orientation' property of the linearlayout in the xml as 'vertical'.
The next part of the problem is the complicated mix of different kinds of layout params, you have correctly identified the need for table and row layout params seperatley but have defined the rowParams variable as a 'new TableLayout.LayoutParams' instead of which it should be 'new TableRow.LayoutParams' but both should have a width of match_parent and a height of wrap_content. Code example below:
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.linearLayout2);
for(int i = 0; i < listItems.length; i++)
{
TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
TableLayout.LayoutParams lp2 = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT);
TableLayout tableLayout = new TableLayout(this);
tableLayout.setLayoutParams(lp2);
tableLayout.setColumnStretchable(0, true);//NOTE: you may not want this if you do not want your textview to always fill the available space
TableRow tableRow = new TableRow(this);
tableRow.setLayoutParams(lp);
TextView textView = new TextView(this);
textView.setText(listItems[i]);
textView.setLayoutParams(lp);
tableRow.addView(textView);
tableLayout.addView(tableRow);
linearLayout.addView(tableLayout);
}
Hope this helps.
This is a XML LinearLayout linlayout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mylinear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
I want to add TextViews to this layout programmatically because the number of TextViews to be added can be different sometimes.
Here is the activity code:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.linlayout);
LinearLayout linear=(LinearLayout) findViewById(R.layout.mylinear);
TextView [] txt =new TextView[3];
for(int i=0;i<txt.length;i++)
{
txt[i]=new TextView(this);
txt[i].setText("text "+i);
txt[i].setLayoutParams(new
LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
linear.addView(txt[i]);
}
}
The LogCat don't display errors but the TextViews are not displayed when I run the app.
I try to put the line:
setContentView(R.layout.linlayout);
at the end, after the for, but doesn't work.
Use this :
TextView [] txt = new TextView[3];
for (int i=0; i<txt.length; i++) {
txt[i] = new TextView(YourActivity.this);
txt[i].setText("text " + i);
txt[i].setLayoutParams(newLayoutParams
(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
linear.addView(txt[i]);
}
It would be best to use a ListView. By the way did you change the orientation of your layout to a vertical orientation ? But if it necessary for you i suggesst this :
i suppose you have an element with a certain size.
final int size = 3; // replace with the size of your element
LinearLayout linear = (LinearLayout) findViewById(R.layout.mylinear);
for(int i=0;i<size;i++){
final TextView textView = new TextView(this);
textView.setText("text "+i);
textView.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
linear.addView(textView);
}