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
Related
I have this layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:background="#000"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal|center_vertical">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/play"
android:gravity="center_horizontal"
android:scaleType="centerInside"
android:text="#string/highScores"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff" />
<View
android:layout_width="1dp"
android:layout_height="20dp"></View>
<TableLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal">
</TableLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
I fill the 'container' TableLayout with elements like this:
layout.addView(buildTitleRow());
for (int i = 0; i < users.length(); i++) {
JSONObject parent = (JSONObject) users.get(i);
layout.addView(buildRowFrom(parent, i + 1));
}
buildTitleRow:
private TableRow buildTitleRow(){
TableRow result = new TableRow(this);
int color = Color.parseColor("#ffff00");
View view = new View(this);
view.setMinimumWidth(10);
result.addView(view);
view = new View(this);
view.setMinimumWidth(10);
result.addView(view);
//the same for other views
return result;
}
buildRowFrom:
private TableRow buildRowFrom(final JSONObject element, int counter) throws JSONException {
TableRow result = new TableRow(this);
String rowName = element.getString("name");
int color = Color.parseColor("#00ff00");
if(rowName.equals(userName)){
color = Color.parseColor("#ffffff");
}
TextView textView = new TextView(this);
textView.setText(counter + ".");
textView.setTextColor(color);
result.addView(textView);
//some other views
return result;
}
this really works well just until the scrolling needs to take place...
Once there are more elements than the height of the screen the table remains scrollable (luckily) but the original 'title' Textview doesn't show up anymore (you can't scroll up towards it anymore)
Does anyone know how to tweak the layout to keep it visible once more elements are added than the size of the screen?
Thanks a lot,
S.
I've tried your code and found find something wrong in your xml layout.
The attribute android:layout_gravity will change the layout's own gravity. So if set this attribute to a LinearLayout with center and its android:layout_height is wrap_content(means that the real height of the 'LinearLayout' will exceed the screen's height) and fill ScrollView(its height is the screen's height) with it, the LinearLayout will align to center of its parent ScrollView.
If you want to keep the content of 'LinearLayout' centered, you can set android:fillViewport="true" to ScrollView and then the LinearLayout will fill the parent and you can use android:gravity="center" on the LinearLayout. Reference
But there is still some thing need to be changed. In your java code, View view = new View(this) this line will new a View and then you add it into TableLayout. But this TableLayout will be full of View because of the description of View below.
* The base class implementation of measure defaults to the background size,
* unless a larger size is allowed by the MeasureSpec. Subclasses should
* override {#link #onMeasure(int, int)} to provide better measurements of
* their content.
You can use a concrete view like TextView instead of it.
I don't know if I have clarified it. I think if you remove the attribute android:layout_gravity of LinearLayout, it will work.
I'm glad if it would help.
I did the adaptations Paul suggested + change android:layout_height of the ScrollView to "wrap_content" to keep the inner LinearLayout centered when the android:layout_gravity="center" was removed from it (see complete layout below).
I wouldn't have found it without Paul's suggestion and explanation so I'll accept his answer as answer, this answer is just for the sake of completeness...
I'm not expecting this question to get that much of attention anyways ;-)
Thanks Paul :-D
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:background="#000"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/play"
android:gravity="center_horizontal"
android:scaleType="centerInside"
android:text="#string/highScores"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff" />
<View
android:layout_width="1dp"
android:layout_height="20dp"></View>
<TableLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal">
</TableLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
Is there any shortcut for making a LinearLayout that gives equal weight to all of its children?
I need to dynamically add views to a linear layout and I want to give equal weights to all of them. Is there any way to to this rather than programmatically add layoutparams to all of the children and then programmatically set the weightSum of the layout to be the number of elements inside the layout?
For that you can give weightsum to linear layout and divide it into equal parts by giving layout_weight to all your views inside linear layout. For example:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:weightSum="3">
<View
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
/>
<View
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
/>
<View
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
/>
</LinearLayout>
Here is some code you can try:
LinearLayout ll = (LinearLayout)findViewById(R.id.linearlayout);
int childcount = ll.getChildCount();
for (int i=0; i < childcount; i++){
View v = ll.getChildAt(i);
LinearLayout.LayoutParams loparams = (LinearLayout.LayoutParams) v.getLayoutParams();
// Set only target params:
loparams.height = 0;
loparams.weight = 1;
v.setLayoutParams(loparams);
}
Ok, it turned out that the weightSum is OPTIONAL, meaning that i could just set weight of all element to be 1 and never needed to touch the weightSum parameter.
thanks you guys for your help!
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 have been trying to get some data to show up in my dialog.
In the dialog I have a checkbox and two buttons that show up, so I know it is loading my layout file.
I am not certain what else to do, so why would the background on my dialog be completely transparent, and more importantly, why can't I see anything in the two views I have experimented with?
Here is my entire layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<CheckBox
android:id="#+id/show_all_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Include books read" />
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button
android:id="#+id/books_by_author_select_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Books" />
<Button
android:id="#+id/books_by_author_cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel" />
</LinearLayout>
<TableLayout android:id="#+id/books_by_author_list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="0">
<TableRow android:id="#+id/TableRow01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="#+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="textfield 1-1"></TextView>
<CheckBox android:id="#+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
</TableRow>
</TableLayout>
</LinearLayout>
I have also tried this with a ListView but the same results. Directly below the two buttons the dialog is transparent.
The TableLayout has nine children when it finishes being initialized, and since it wasn't showing up, I then added the TableRow in the xml above, originally that block wasn't there.
this.mContext = context;
setContentView(R.layout.books_by_author);
final TableLayout view = (TableLayout) findViewById(R.id.books_by_author_list);
for(int position = 0; position < list.size(); position++) {
TableLayout table = (TableLayout) findViewById(R.id.books_by_author_list);
// create a new TableRow
TableRow row = new TableRow(mContext);
// create a new TextView
TextView t = new TextView(mContext);
// set the text to "text xx"
t.setText(list.get(position).mTitle);
// create a CheckBox
CheckBox c = new CheckBox(mContext);
// add the TextView and the CheckBox to the new TableRow
row.addView(t);
row.addView(c);
// add the TableRow to the TableLayout
table.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
view.invalidate();
I have tried this with a ListView and just using an ArrayAdapter, and I have created a custom adapter extending ArrayAdapter and BaseAdapter.
I have also explicitly set the background of the ListView and TableLayout to be Color.YELLOW, and tried setting other colors, but nothing helps.
TableLayout doesn't work in many cases. Moreover, while running your app, TableLayout creates problem.
Always prefer using LinearLayout or FrameLayout.
Linearlayout can fit at any place where you are using TableLayout.
Solution: The problem was that the LinearLayout containing the buttons has fill_parent instead of wrap_content for the layout_height attribute.