Trying to do a dynamic TableLayout in Android.
In my layout there is only this:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_table"
android:orientation="vertical"
android:background="#android:color/background_dark"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
</TableLayout>
I want to dynamically add rows (and columns) to this table, because at compile time it is unknown how many cells will I need to display.
What is known for sure however, that the whole table must fit to the screen (fit and stretch actually).
I created a layout for the rows too (for now with 2 fixed cells):
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:text="Rate User1"
/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:text="Rate User2"
/>
</TableRow>
In the activity's onCreate function I'm inflating 3 rows and I expect them to lay all over the screen:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater inflater = getLayoutInflater();
TableLayout tableLayout = findViewById(R.id.main_table);
TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 0, 1f /*0.33f*/);
TableRow tableRow1 = (TableRow)inflater.inflate(R.layout.item_stream_row, tableLayout, false);
tableRow1.setLayoutParams(rowParams);
TableRow tableRow2 = (TableRow)inflater.inflate(R.layout.item_stream_row, tableLayout, false);
tableRow2.setLayoutParams(rowParams);
TableRow tableRow3 = (TableRow)inflater.inflate(R.layout.item_stream_row, tableLayout, false);
tableRow3.setLayoutParams(rowParams);
//tableLayout.setWeightSum(1f);
tableLayout.addView(tableRow1);
tableLayout.addView(tableRow2);
tableLayout.addView(tableRow3);
}
But for now the row heights matches their content instead of stretching to the whole screen:
If I comment out the addViews, and put 3 TableRows into the main layout, it looks like as I want:
So the question is how can I achieve my desired result (2nd image), if putting rows directly into the layout file is not an option?
Solution was to change the LayoutParams of TableRow:
TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 0, 1f);
to LayoutParams of TableLayout:
TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT, 1f);
After this change the layout is stretching to the whole screen.
Related
I am trying to inflate a layout resource and move some views in it to a table. I remove the views from their parents and then add them to the table. It works but what I really need is to add them to a TableRow in the table instead. However, when I tried to do that, nothing showed up.
To simplify the example, I just use views in an xml instead of ones generated in code. In the following xml, there are a TableLayout with one TableRow and an ImageButton:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...>
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/table">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/row_1"></TableRow>
</TableLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button" />
</RelativeLayout>
If I move the button to the table, it works:
Button button = (Button ) getActivity().findViewById(R.id.button);
TableLayout table = (TableLayout) getActivity().findViewById(R.id.table);
TableRow row = (TableRow) getActivity().findViewById(R.id.row_1);
((ViewGroup)button.getParent()).removeView(button);
table.addView(button);
However, if I move it to the TableRow, the button won't show up.
row.addView(button);
Does anyone have a solution?
Try to add the Button to a row like this:
row.addView(button,new TableRow.LayoutParams(
TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT));
I am trying to use the Library SwipeLayout (https://github.com/daimajia/AndroidSwipeLayout) to make a table of swipeable rows (that is, to achieve this effect). I want to create the table dynamically (with Java, not xml). The table (if it were to exist as xml) should look like this:
...TableLayout...
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="0dp">
<com.daimajia.swipe.SwipeLayout
android:id="#+id/swipe"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- The first view in SwipeLayout is the delete button hidden behind -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:id="#+id/delete1"
android:gravity="center"
android:padding="16dp"
android:background="#FF0000"
android:textSize="22sp"
android:text="Delete"/>
<GridLayout android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="#drawable/bottom_border_light_solid"
android:columnCount="2"
android:padding="10dp">
...TextViews...
</GridLayout>
</com.daimajia.swipe.SwipeLayout>
</TableRow>
.../TableLayout...
My table creation code looks like this:
TableRow row = new TableRow(c);
SwipeLayout swipeLayout = new SwipeLayout(c);
TextView delete = generateDeleteButton(c); //I have confirmed that this function works
GridLayout cell = generateRoutineLayout(c); //I have confirmed that this function works
swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown);
swipeLayout.addDrag(SwipeLayout.DragEdge.Left, delete);
swipeLayout.addSwipeListener(swipeListener);
cell.setPadding(5, 5, 5, 5);
swipeLayout.addView(delete);
swipeLayout.addView(cell);
TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
swipeLayout.setLayoutParams(lp);
row.addView(swipeLayout);
TableRow.LayoutParams rl = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT);
row.setLayoutParams(rl);//TableRow.LayoutParams.WRAP_CONTENT));
row.setPadding(0, 0, 0, 0);
I have confirmed that generateRoutineLayout(c) works properly and generates a correct GridLayout. After closely inspecting the Tree View in Android monitor it is clear that the grid layout IS added to the SwipeLayout and IS properly sized, but it is simply not appearing!
I know that SwipeLayout extends FrameLayout. Is it possible that I can't insert a GridLayout into a FrameLayout?
Thanks
Try having RelativeLayout inside your FrameLayout and then add your GridLayout inside the RelativeLayout.
Hope this helps you.
I am trying to display 9 images on my screen in 3x3 matrix format so that it fits to screen perfectly.
I am able to get the desired result using xml, but I am not able to replicate the same by creating controls through code.
(3 columns fit to my screen perfectly but the rows are not resizing to fit to screen)
Please suggest a way through which I can create dynamic controls through code and get the desired results.
Note : I want everything to fit in my screen in a matrix format, but without scrollbars. (I was unable to achieve this using grid layout)
Here is my xml :
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<TableRow
android:gravity="center"
android:layout_weight="1">
<ImageView
android:layout_width="1dp"
android:layout_height="match_parent"
android:src="#drawable/icon"
android:layout_weight="1"
android:layout_gravity="center"/>
<ImageView
android:layout_width="1dp"
android:layout_height="match_parent"
android:src="#drawable/encrypt"
android:layout_weight="1"
android:layout_gravity="center"/>
<ImageView
android:layout_width="1dp"
android:layout_height="match_parent"
android:src="#drawable/gear"
android:layout_weight="1"
android:layout_gravity="center"/>
</TableRow>
<TableRow
android:gravity="center"
android:layout_weight="1">
.
.//Same as row 1
</TableRow>
<TableRow
android:gravity="center"
android:layout_weight="1">
.
.//Same a row 1
</TableRow>
</TableLayout>
This produces an output in matrix format, resizing cells to fit to screen.
But I am not able to replicate the same result when I am creating controls through code. This is code that I am using :
TableLayout simple_game = new TableLayout(this);
simple_game.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.MATCH_PARENT));
for(int i=0;i<3;i++)
{
TableRow tr = new TableRow(this);
simple_game.addView(tr);
TableLayout.LayoutParams trPara = new TableLayout.LayoutParams();
trPara.weight = 1f;
trPara.gravity = Gravity.CENTER;
tr.setLayoutParams(trPara);
for(int j=0;j<3;j++)
{
ImageView iv = new ImageView(this);
iv.setImageResource(I[i][j]);
tr.addView(iv);
TableRow.LayoutParams trPara2 = new TableRow.LayoutParams();
trPara2.width = 1;
trPara2.height = ViewGroup.LayoutParams.MATCH_PARENT;
trPara2.weight = 1f;
trPara2.gravity = Gravity.CENTER;
iv.setLayoutParams(trPara2);
}
}
setContentView(simple_game);
Using this code, the columns are resizing themselves to fit to screen but the rows are not resizing.
The answer is LinearLayout and the weight attribute.
You can:
Dynamically add a LinearLayout 'horizontal'.
Add 3 LinearLayout s 'vertical' to the horizontal layout.
Add 3 images to each of the vertical layouts.
Set the weight of each vertical layout to 1.
Set the weight of each image to 1.
Note: weight doesn't work well with grid layout until API level 21 or 22, so if that is your target grid layout might be the way to go.
This explains creating layouts dynamically.
I'm using a TableLayout with 3 rows, and 3 imagebuttons in each row. I want to keep the aspect ratio of the images.
I have defined a layout like this:
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#000000"
android:padding="0dp" >
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="0dp" >
<ImageButton
android:layout_weight="1"
android:adjustViewBounds="true"
android:contentDescription="#string/Cell"
android:padding="0dp"
android:scaleType="fitCenter"
android:src="#drawable/empty" >
</ImageButton>
<!-- Two more images like above -->
</TableRow>
<!-- Two more rows like above -->
</TableLayout>
With this layout, I get something like this:
http://i.stack.imgur.com/reoSd.png
As you can see, strange holes between rows in the last column appear. I dont know why, but if I change the TableLayout margin to 0dp, this problem dissapears:
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:background="#000000"
android:padding="0dp" >
And the result:
http://i.stack.imgur.com/Jytix.png
Why this behavior? What I am doing wrong? I have tested this, with many devices on the emulator and I always get the same. As additional information, I have printed the size and padding of the images of the last column and the first dinamically with getHeight() and getWidth()..., and i always get exactly the same.
I had this issue, you should use relative layout instead... If you still want to use Table layout, try :
TableLayout tableView = (TableLayout) findViewById(R.id.tableView);
TableRow row = (TableRow) inflater.inflate(R.layout.tablerow, tableView, false);
ImageView imgDis = (ImageView) row.findViewById(R.id.spinnerEntryContactPhoto);
imgDis.setPadding(5, 5, 5, 5);
imgDis.setAdjustViewBounds(true);
// set row height width
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, 50);
params.topMargin = 0;
params.bottomMargin = 0;
params.leftMargin = 0;
params.rightMargin = 0;
Hope this help
I am trying to make a day-calendar and for that I am using a tablelayout and I then want to define a custom row(layout xml) containing TextViews to be able to access data here is and example of my table layout:
<TableLayout
android:id="#+id/appointmentListView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow
android:id="#+id/tableRow1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/unitNul"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00"/>
<CustomRow><\CustomRow> //this is where I imagined I would have to put my custom element
</LinearLayout>
</TableRow>
I would then proceed to put in appointments based on their time of the day in the correct rows (via. switch logic)
My questions are:
How do I add a Custom element to each tablerow?
Is this the best way to do so?
side note:
I have tried to make a custom view element, but this seems to be a bit too dificult for me to handle. (this is also an option if you know a good guide explaining this)
I have already tried: http://developer.android.com/guide/topics/ui/custom-components.html
create an Xml like this::
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
android:id="#+id/tablerows"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/white"
android:stretchColumns="0,1" >
</TableLayout>
</LinearLayout>
</LinearLayout>
then in activity class dynamically add rows and the other views like this;;
TableRow row;
TextView t1, t2;
int dip = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,(float) 1, getResources().getDisplayMetrics());
row = new TableRow(context);
row.setLayoutParams(new android.widget.TableRow.LayoutParams(android.widget.TableRow.LayoutParams.FILL_PARENT,
android.widget.TableRow.LayoutParams.WRAP_CONTENT));
t1 = new TextView(context);
t1.setTypeface(null, 1);
t1.setTextSize(15);
t1.setWidth(50 * dip);
t1.setPadding(20*dip, 0, 0, 0);
row.addView(t1);
then in ur table(here "myTable") add the row like this::
myTable.addView(row, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));