I have a table that covers-up entire screen and contains variable number of rows.
I would like to know how can i distribute these rows vertically uniformly, so that they take up entire tables' space.
I have tried layout_weight, and weightSum, but its not working.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout01"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="0,1,2"
android:id="#+id/maintable"
android:weightSum="3" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_weight="1" >
<TextView
android:text="text 1_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="text 2_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="text 3_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_weight="1" >
<TextView
android:text="text 1_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="text 2_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="text 3_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_weight="1" >
<TextView
android:text="text 1_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="text 2_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="text 3_3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</TableRow>
</TableLayout>
</LinearLayout>
Your code looks wrong as your are not setting 'fill parent' constraint for the vertical
axis
<TableRow
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_weight="1" >
should be
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
Please check below code. This will cover entire screen with table rows uniformly
grid_layout.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tableLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</TableLayout>
grid_layout is filled with text views in code as below
public class GridLayoutActivity extends Activity {
private static final int NO_OF_ROWS = 5;
private static final int NO_OF_COLUMS = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_layout);
TableLayout gridview = (TableLayout) findViewById(R.id.tableLayout);
for (int rowCnt = 0 ; rowCnt < NO_OF_ROWS; rowCnt++) {
TableRow row = new TableRow(this);
TableLayout.LayoutParams tableLayoutLP = new TableLayout.LayoutParams();
tableLayoutLP.weight = 1;
row.setLayoutParams(tableLayoutLP);
for (int column = 0; column < NO_OF_COLUMS; column++) {
TextView tv = new TextView(this);
TableRow.LayoutParams tableRowLP = new TableRow.LayoutParams();
tableRowLP.setMargins(2, 2, 2, 2);
tableRowLP.weight=1;
tableRowLP.height = TableRow.LayoutParams.MATCH_PARENT;
tv.setTextColor(Color.WHITE);
tv.setGravity(Gravity.CENTER);
tv.setBackgroundColor(Color.DKGRAY);
tv.setLayoutParams(tableRowLP);
tv.setText("YourText");//Add your text here
row.addView(tv);
}
gridview.addView(row);
}
}
}
Related
how to create this kind of layout in android
i have tried using table layout. but getting error in creating this.
please check my code i am able to display images. 1 image in 1 row. but i want 2 small images in 1 row. and continues.
here is my code
private void getBannerList() {
final Call<BannerList_Model> itemMainResponse = APIHandler.getApiService().bannerList(getFiledMapForItemList());
itemMainResponse.enqueue(new Callback<BannerList_Model>() {
#Override
public void onResponse(Response<BannerList_Model> response, Retrofit retrofit) {
BannerList_Model itemResponse = null;
itemResponse = response.body();
if (itemResponse == null) {
UIUtils.showToast(getContext(), "Server Error !");
} else {
String msg = itemResponse.getMsg().toString();
if (msg.equals("success")) {
userList = itemResponse.getBannerList();
if(userList != null) {
TableLayout table = (TableLayout) view.findViewById(R.id.tblBanner_list);
table.setColumnStretchable(0,true);
table.setColumnStretchable(1,true);
int tsize = userList.size();
TextView[] t1 = new TextView[tsize];
ImageView[] img = new ImageView[tsize];
for(int i=0; i<userList.size();i++)
{
TableRow row = new TableRow(getContext());
String banner_size = userList.get(i).getBannerSize().toString();
img[i] = new ImageView(getContext());
Picasso.with(getContext())
.load(Constants.VIDEO_URL + userList.get(i).getBannerUrl())
.into(img[i]);
row.addView(img[i]);
table.addView(row);
}
}
}
}
}
}
});
}
here is the video how i want layout
http://shrivivah.com/layout.mp4
if there is 2 small images than it will display in 1 row.
if there is 2 medium or full size image than it will display in 1 row each.
if 1 small and 2 medum than 1 image per row to display.
layout image
Your mistake is that you are adding TextView to TableRow(row) but you didn't add row to TableLayout. Here is an example for what you need. You can set some margins and add button.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TableLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TableRow
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
</TableRow>
</TableLayout>
</LinearLayout>
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.tops.stackoverflow.MainActivity">
<LinearLayout
android:id="#+id/llShortcutParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:elevation="20dp"
android:padding="10dp"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:elevation="20dp"
android:padding="10dp"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:duplicateParentState="true"
android:elevation="20dp"
android:padding="10dp"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Button1"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Button1"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
I'm fairly new to android and xml layouting. I've been trying to make an app, and already done with the programming bit. However i'm stuck on the finalisation of the layout. Really need a hand. My app should look like this:
I've divided the screen in 4 Linear Layouts as I have numbered in the picture as seen below:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.FirstVersion.android.cwd.Play"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#color/material_blue_grey_800">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnGoBack"
android:text="Go Back"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profile Information"
android:background="#color/accent_material_dark"
android:layout_weight="10" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/LDrawerAction"
android:text="Menu"
android:clickable="false"
android:layout_weight="1"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
</LinearLayout>
//endregion
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Section2"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Section3"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="5sp"
android:textColor="#color/colorWhite"
android:background="#990000"
android:maxLines = "3"
android:scrollbars = "vertical"
android:id="#+id/txtSection3" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="15"
android:orientation="vertical"
android:baselineAligned="false">
<TableLayout
android:id="#+id/Section4"
android:layout_width="match_parent"
android:layout_weight="15"
android:layout_height="wrap_content">
</TableLayout>
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
The problem now is that, the second section is filled programmatically and it has a range of rows from 8 to 14. The same for the columns. Every block is a different button which I add with this code:
Lay= (LinearLayout)findViewById(R.id.Section2);
for (int row = 0; row < numberOfRows; row++)
{
LinearLayout Linearrow = new LinearLayout(this);
Linearrow.setOrientation(LinearLayout.HORIZONTAL);
for (int column = 0; column < numberOfColumns; column++)
{
View a = Chosen.blocks[row][column]; //This is a View the extend Button that has no layout properties defined
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, 1.0f);
a.setLayoutParams(params);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
lp.weight = 1.0f;
Linearrow.addView(a, lp);
}
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
lp.weight = 1.0f;
Lay.addView(Linearrow, lp);
}
I have tried even using a TableLayout and assigning a small image as background so it could get resized with the following code:
TL =(TableLayout)fa.findViewById(R.id.Section2);
for (int i = 0; i < numberOfRows; i++)
{
TableRow tableRow = new TableRow(c);
for(int j = 0; j < numberOfColumns; j++)
{
String s = T[(i * 10) + j];
Block b = new Block(c, s);
//int w = Math.round(c.getResources().getDisplayMetrics().density * 20);
//int h = Math.round(c.getResources().getDisplayMetrics().density * 80);
//b.setLayoutParams(new TableRow.LayoutParams(w, h, 2.0f));
b.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT, 1f));
b.setBackgroundResource(R.drawable.g_3);
tableRow.addView(b);
tableRow.setLayoutParams(new android.widget.LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 5f));
final Block fb = b;
}
TL.addView(tableRow);
}
When I run the app, I can see that unless I open it on a big screen phone, the content is not visible entirely(as if the height is set fixed manually of the layouts), and since it is not scroll-able, the content is not visible. How can I rearrange or modify the layout so it looks as in the picture above?
Make fixed height of layouts using layout_weight
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1"
android:weightSum="12"
android:orientation="horizontal"
android:background="#color/material_blue_grey_800">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnGoBack"
android:text="Go Back"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profile Information"
android:background="#color/accent_material_dark"
android:layout_weight="10" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/LDrawerAction"
android:text="Menu"
android:clickable="false"
android:layout_weight="1"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.4"
android:weightSum="1"
android:id="#+id/Section2"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1"
android:id="#+id/Section3"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="5sp"
android:textColor="#android:color/white"
android:background="#990000"
android:maxLines = "3"
android:scrollbars = "vertical"
android:id="#+id/txtSection3" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.4"
android:weightSum="15"
android:orientation="vertical"
android:baselineAligned="false">
<TableLayout
android:id="#+id/Section4"
android:layout_width="match_parent"
android:layout_weight="15"
android:layout_height="wrap_content">
</TableLayout>
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
And in your java class where you add views dynamically, calculate the weights of children accordingly as given below
Lay= (LinearLayout)findViewById(R.id.Section2);
Lay.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int totalWidth = Lay.getMeasuredWidth();
float rowWeight = 1 / numberOfRows;
int columnWidth = totalWidth / numberOfColumns;
for (int row = 0; row < numberOfRows; row++)
{
LinearLayout Linearrow = new LinearLayout(this);
Linearrow.setOrientation(LinearLayout.HORIZONTAL);
for (int column = 0; column < numberOfColumns; column++)
{
View a = Chosen.blocks[row][column]; //This is a View the extend Button that has no layout properties defined
// height is determined by row's layout weight
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(columnWidth,
LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
a.setLayoutParams(params);
Linearrow.addView(a);
}
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
lp.weight = rowWeight;
Lay.addView(Linearrow, lp);
}
I've not tested these, but just might work with few changes that you can figure out once you run this code.
Use
android:layout_weight
attribute to arrange in equal parts in linear layout.
See in the Link
It is better to use View inside ScrollView. Use the below code:-
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.FirstVersion.android.cwd.Play"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#color/material_blue_grey_800">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnGoBack"
android:text="Go Back"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profile Information"
android:background="#color/accent_material_dark"
android:layout_weight="10" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/LDrawerAction"
android:text="Menu"
android:clickable="false"
android:layout_weight="1"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp" />
</LinearLayout>
//endregion
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Section2"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Section3"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="5sp"
android:textColor="#color/colorWhite"
android:background="#990000"
android:maxLines = "3"
android:scrollbars = "vertical"
android:id="#+id/txtSection3" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="15"
android:orientation="vertical"
android:baselineAligned="false">
<TableLayout
android:id="#+id/Section4"
android:layout_width="match_parent"
android:layout_weight="15"
android:layout_height="wrap_content">
</TableLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
I am working on an android project and I have a table layout. I have the Table Layout with one row in the XML layout file for the table headings. The rest of the table is populated dynamically from the result of an API.
I'm adding the views to the table layout, but the rows I'm adding dynamically appear above the table headings.
Below is my XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/toolbar" />
<TableLayout android:id="#+id/tblAuthenticatedDevices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:shrinkColumns="false"
android:layout_margin="10dp"/>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/cardToolbar">
<TextView
android:text="Device Name"
android:layout_width="0dp"
android:layout_weight="1"
android:textStyle="bold"
android:padding="10dp"
android:textColor="#color/white" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="Last Logged In"
android:textStyle="bold"
android:padding="10dp"
android:textColor="#color/white" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="From"
android:textStyle="bold"
android:padding="10dp"
android:textColor="#color/white"/>
</TableRow>
</LinearLayout>
Below is how I am populating the rest of the table
JSONArray dataObject = jsonObject.getJSONArray(Defines.JSONElements.DATA);
for (int i = 0; i < dataObject.length(); i++)
{
TableRow row = (TableRow)getLayoutInflater().inflate(R.layout.table_row_layout, tblAuthenticatedDevices, false);
JSONObject deviceData = dataObject.getJSONObject(i);
TextView txtDeviceName = new TextView(AuthenticatedDevices.this);
txtDeviceName.setText(deviceData.getString("DeviceName"));
row.addView(txtDeviceName);
TextView txtLastLoggedIn = new TextView(AuthenticatedDevices.this);
txtLastLoggedIn.setText(deviceData.getString("LastLoggedIn"));
row.addView(txtLastLoggedIn);
TextView txtLocation = new TextView(AuthenticatedDevices.this);
txtLocation.setText(String.format("%s - %s", deviceData.getString("Country"), deviceData.getString("City")));
row.addView(txtLocation);
tblAuthenticatedDevices.addView(row);
}
Just to re-iterate, the row data that I am dynamically adding to the table appears above the row headings I've added to my XML layout. I expected the row headings to appear, then below that would appear the rows that I am adding to the table.
Okay, so I've been researching regarding TableLayouts where there is always a header included to them, and basically, all of them just adds the TableRow header first via code, in order for it to be on top. So here's what I did as a reference for you.. First, I just did a separate layout for the header.
tr_header.xml
<?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">
<TextView
android:textStyle="bold"
android:id="#+id/tv_device_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="device name" />
<TextView
android:id="#+id/tv_last_login"
android:textStyle="bold"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="last_login" />
<TextView
android:id="#+id/tv_location"
android:layout_width="0dp"
android:textStyle="bold"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="location" />
</TableRow>
Then in the layout of the activity where the tableLayout is, I just kept it empty, like so...
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.aalawi.myapplication.MainActivity">
<TableLayout
android:id="#+id/tblAuthenticatedDevices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:shrinkColumns="false"
android:stretchColumns="1" />
</LinearLayout>
And then in the code, I just add first the header, then iterated on some sample data afterwards. Also, I presume you also have a different layout for your table_rows as mentioned in the code you provided (named table_row_layout), so I just did something similar.
tl_row.xml
<?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:orientation="horizontal"
android:weightSum="3">
<TextView
android:id="#+id/tv_device_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
<TextView
android:id="#+id/tv_last_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
<TextView
android:id="#+id/tv_location"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
</TableRow>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TableLayout tl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
tl = (TableLayout) findViewById(R.id.tblAuthenticatedDevices);
List<String> deviceNames = Arrays.asList("1", "2", "3");
List<String> lastLogin = Arrays.asList("11", "22", "33");
List<String> location = Arrays.asList("111", "222", "333");
// Add Header First...
TableRow header = (TableRow) getLayoutInflater().inflate(R.layout.tr_header, null);
tl.addView(header);
// Fill additional rows...
for (int i = 0; i < deviceNames.size(); i++) {
TableRow row = (TableRow) getLayoutInflater().inflate(R.layout.tl_row, tl, false);
TextView txtDeviceName = (TextView) row.findViewById(R.id.tv_device_name);
TextView txtLastLoggedIn = (TextView) row.findViewById(R.id.tv_last_login);
TextView txtLocation = (TextView) row.findViewById(R.id.tv_location);
txtDeviceName.setText(deviceNames.get(i));
txtLastLoggedIn.setText(lastLogin.get(i));
txtLocation.setText(location.get(i));
tl.addView(row);
}
}
}
That resulted to this.
Add this before you create your data rows to create the header:
TableRow rowHeader = new TableRow(context);
rowHeader.setBackgroundColor(Color.parseColor("#c0c0c0"));
rowHeader.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
//Title header for each column here
String[] headerText={"ID","NAME","TYPE"};
for(String c:headerText) {
TextView tv = new TextView(this);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(18);
tv.setPadding(5, 5, 5, 5);
tv.setText(c);
rowHeader.addView(tv);
}
tableLayout.addView(rowHeader);
I've realised what I've done wrong when I took another look this morning.
I've ended the Table Layout (i.e. I have <TableLayout... />) then I've added my TableRow but its outside the TableLayout.
Instead I have put my headings inside the TableLayout tag as below and it works as expected.
<TableLayout android:id="#+id/tblAuthenticatedDevices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:shrinkColumns="false"
android:layout_margin="10dp">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/cardToolbar">
<TextView
android:text="Device Name"
android:layout_width="0dp"
android:layout_weight="1"
android:textStyle="bold"
android:padding="10dp"
android:textColor="#color/white" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="Last Logged In"
android:textStyle="bold"
android:padding="10dp"
android:textColor="#color/white" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="From"
android:textStyle="bold"
android:padding="10dp"
android:textColor="#color/white"/>
</TableRow>
</TableLayout>
I am using TableLayout and Some TableRow elements has ListView inside. Until I load data in ListView All Items in TableRow works fine. As Data has been loaded in ListViews layout_width match_parent and fill_parent stops working.
Note: In this Question I am asking about layout_width issue. My layout_height is working great and also I don't have scrolling issue.
Following is the XML of my Layout.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TableRow
android:id="#+id/tr_lbl_topSongs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/app_orange"
android:padding="5dp" >
<TextView
android:id="#+id/tv_lbl_topSongs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Songs"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/app_white" />
</TableRow>
<TableRow
android:id="#+id/tr_content_topSongs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ListView
android:id="#+id/lv_topSongs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</TableRow>
<TableRow
android:id="#+id/tr_viewMore_topSongs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:background="#color/app_offwhite"
android:gravity="center_horizontal|center_vertical"
android:padding="5dp" >
<TextView
android:id="#+id/tv_viewMore_topSongs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View More"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/app_gray" />
</TableRow>
<TableRow
android:id="#+id/tr_lbl_topVideos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/app_orange"
android:padding="5dp" >
<TextView
android:id="#+id/tv_lbl_topVideos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Videos"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/app_white" />
</TableRow>
<TableRow
android:id="#+id/tr_content_topVideos"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ListView
android:id="#+id/lv_topVideos"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</TableRow>
<TableRow
android:id="#+id/tr_viewMore_topVideos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:background="#color/app_offwhite"
android:gravity="center_horizontal|center_vertical"
android:padding="5dp" >
<TextView
android:id="#+id/tv_viewMore_topVideos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View More"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/app_gray" />
</TableRow>
<TableRow
android:id="#+id/tr_lbl_topRingtones"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/app_orange"
android:padding="5dp" >
<TextView
android:id="#+id/tv_lbl_topRingtones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Ringtones"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/app_white" />
</TableRow>
<TableRow
android:id="#+id/tr_content_topRingtones"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ListView
android:id="#+id/lv_topRingtones"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</TableRow>
<TableRow
android:id="#+id/tr_viewMore_topRingtones"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:background="#color/app_offwhite"
android:gravity="center_horizontal|center_vertical"
android:padding="5dp" >
<TextView
android:id="#+id/tv_viewMore_topRingtones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View More"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/app_gray" />
</TableRow>
</TableLayout>
</ScrollView>
Update:
I have managed to use ListView inside of ScrollView with following codes.
I registered TouchListner
lv_topSongs = (ListView) rootView.findViewById(R.id.lv_topSongs);
lv_topSongs.setOnTouchListener(this);
My TouchListner in which I am passing touch event to ScrollView and Disabling Touch Even on ListView.
#Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
mScrollView.onTouchEvent(event);
return false;
}
I am setting height after loading data in ListView With following Code.
setListViewHeightBasedOnChildren(lv_topSongs);
And My setListViewHeightBasedOnChildren function
/**** Method for Setting the Height of the ListView dynamically.
**** Hack to fix the issue of not showing all the items of the ListView
**** when placed inside a ScrollView ****/
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
params.width = LayoutParams.MATCH_PARENT;
listView.setLayoutParams(params);
listView.requestLayout();
}
Screenshot
I solved this Problem by Assigning weight to ListView android:layout_weight="1".
Still unable to understand why I have to assign weight even there is only one Item in TableRow however This solved my problem.
If you want your list to fill the height equal to your table row you will have to give some fixed height to your table row..
Try it.
This is my main.xml:`
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:addStatesFromChildren="false"
android:layout_height="wrap_content">
<TableLayout
android:id="#+id/header"
android:layout_marginRight="2dp"
android:layout_marginLeft="2dp"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:layout_width="fill_parent"
android:layout_alignParentTop="true">
<TableRow>
<TextView
android:id="#+id/leftHeader"
android:textColor="#android:color/black"
android:layout_margin="1dp"
android:gravity="center_horizontal"
android:layout_weight="1"
android:background="#ffcccccc"
android:text="textview1"
android:layout_width="30dip" />
<TextView
android:id="#+id/rightHeader"
android:textColor="#android:color/black"
android:gravity="center_horizontal"
android:layout_weight="1"
android:layout_margin="1dp"
android:background="#android:color/white"
android:text="textview2"
android:layout_width="70dip" />
</TableRow>
</TableLayout>
<ScrollView
android:id="#+id/table_scroll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="2dp"
android:layout_marginLeft="2dp"
android:layout_below="#+id/header"
android:layout_above="#+id/buttonTable">
<TableLayout
android:id="#+id/maintable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/black">
<TableRow
android:id="#+id/maintableRow">
<TextView
android:id="#+id/maintableLeft"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginRight="1dp"
android:layout_marginLeft="1dp"
android:text="textview1"
android:layout_width="30dip" />
<TextView
android:id="#+id/maintableRight"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:text="textview2"
android:layout_width="70dip" />
</TableRow>
</TableLayout>
</ScrollView>
<TableLayout
android:id="#+id/buttonTable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:layout_alignParentBottom="true">
<TableRow>
<Button
android:id="#+id/button_ResetData"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Reset Data"
android:layout_gravity="center"
android:layout_weight="1" />
<Button
android:id="#+id/button_Refresh"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Refresh"
android:gravity="center"
android:layout_weight="1" />
</TableRow>
</TableLayout>
`
After I press one of the buttons its text alignment goes to the left, how can I make it stay in center?
something similar happens with the first table (header) (textview1, textview2) but here it also reduses the textsize the amount of the text in the view...
EDIT: I managed to find the code that causes the change but I don't know how to fix this.
Maybe some one can explain me why does this happen and how to fix it?
private void fillTableView(List<BatteryInfo> list) {
TextView leftHeader = (TextView) findViewById(R.id.leftHeader);
TextView rightHeader = (TextView) findViewById(R.id.rightHeader);
LayoutParams leftHeaderLayoutParams = leftHeader.getLayoutParams();
LayoutParams rightHeaderLayoutParams = rightHeader.getLayoutParams();
TableLayout contentTable = (TableLayout) findViewById(R.id.maintable);
contentTable.removeAllViews();
for (int i = list.size() - 1; i >= 0; i--) {
TextView tv1 = new TextView(this);
tv1.setTextColor(Color.BLACK);
tv1.setGravity(Gravity.CENTER);
tv1.setBackgroundColor(Color.LTGRAY);
tv1.setLayoutParams(leftHeaderLayoutParams);
tv1.setText(String.valueOf(list.get(i).getLevel()));
TextView tv2 = new TextView(this);
tv2.setTextColor(Color.BLACK);
tv2.setGravity(Gravity.CENTER);
tv2.setBackgroundColor(Color.WHITE);
tv2.setLayoutParams(rightHeaderLayoutParams);
tv2.setText(list.get(i).getDurationTimeInString());
TableRow tblRow = new TableRow(this);
tblRow.addView(tv1);
tblRow.addView(tv2);
contentTable.addView(tblRow);
}
}
After I use removeAllViews or any addView function the layout of the top most table changes as I explained before. Why does this happen?
You can fix this by changing the android:layout_width="30dip" and android:layout_width="70dip" in leftHeader and rightHeader to android:layout_width="fill_parent". I have to admit that I'm not entirely certain why that is, though.
Instead of clearing and re-filling a TableLayout every time, though, you might want to consider using a ListAdapter. It's much more suited to what you're doing (and will probably perform better, too).
UPDATE NUMBER 2:
Notice the change in the main.xml and the change in the onCreate method. This will make your header static while letting your listview scroll, and changing from TableLayout to LinearLayout for your buttons will fix the alignment issue.
Here's how to do this with a custom adapter instead of TableLayout (which isn't really meant for dynamic data like this):
Change you main.xml to this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:addStatesFromChildren="false" android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:id="#+id/header">
<TextView android:id="#+id/leftHeader" android:textColor="#android:color/black"
android:layout_margin="1dp" android:gravity="center_horizontal"
android:layout_weight="1" android:background="#ffcccccc" android:text="textview1"
android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<TextView android:id="#+id/rightHeader" android:textColor="#android:color/black"
android:gravity="center_horizontal" android:layout_weight="1"
android:layout_margin="1dp" android:background="#android:color/white"
android:text="textview2" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:id="#+id/buttonTable" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#android:color/black"
android:layout_alignParentBottom="true" >
<Button android:id="#+id/button_ResetData"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:text="Reset Data" android:layout_gravity="center"
android:layout_weight="1" />
<Button android:id="#+id/button_Refresh"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:text="Refresh" android:gravity="center"
android:layout_weight="1" />
</LinearLayout>
<ListView android:id="#+id/listView" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_weight="1"
android:fadingEdge="none"
android:layout_below="#id/header" android:layout_above="#id/buttonTable">
</ListView>
Add XML layout files for your rows (row.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<TextView android:id="#+id/maintableLeft"
android:layout_height="wrap_content" android:layout_weight="1"
android:layout_marginRight="1dp" android:layout_marginLeft="1dp"
android:gravity="center_horizontal" android:background="#ffcccccc"
android:textColor="#android:color/black" android:layout_width="fill_parent" />
<TextView android:id="#+id/maintableRight"
android:layout_height="wrap_content" android:background="#ffcccccc"
android:textColor="#android:color/black" android:layout_weight="1"
android:layout_marginLeft="1dp" android:layout_marginRight="1dp"
android:gravity="center_horizontal" android:layout_width="fill_parent" />
</LinearLayout>
Now everything is in place to create a custom class from BaseAdapter to display your information (and make your layout work better):
class CustomAdapter extends BaseAdapter {
private List<BatteryInfo> info;
private LayoutInflater inflater;
public CustomAdapter(Context context, List<BatteryInfo> x) {
this.info = x;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return info.size();
}
public Object getItem(int position) {
return info.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v;
v = inflater.inflate(R.layout.row, parent, false);
BatteryInfo b = (BatteryInfo) getItem(position);
((TextView) v.findViewById(R.id.maintableLeft)).setText(b
.getDurationTimeInString());
((TextView) v.findViewById(R.id.maintableRight)).setText(b
.getLevel());
return v;
}
}
Modify your onCreate method to inflate the header, add it, and then bind your data to your ListView using the new CustomAdapter (I've created a fake BatteryInfo class for this example, you'll need to modify things slightly to get this working):
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ListView lv = (ListView) this.findViewById(R.id.listView);
final Context context = this;
Button refresh = (Button) this.findViewById(R.id.button_Refresh);
refresh.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
List<BatteryInfo> x = new ArrayList<BatteryInfo>();
x.add(new BatteryInfo());
x.add(new BatteryInfo());
x.add(new BatteryInfo());
x.add(new BatteryInfo());
lv.setAdapter(new CustomAdapter(context, x));
}
});
}