Programmatically create a textview with 0dp and layout weight 1 - android

I am working on an Android project and I have an issue with the layout.
What I have is a JSONArray that I loop round inflating a new TableRow and within the loop round another array within the JSON array to populate it with fields. The fields are populated by inflating an XML file and adding this view to the table row. However, at the moment nothing shows up in the row.
Below is my TableRow XML file:
<?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="wrap_content"
android:background="#color/white"/>
Below is my TextView XML:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/black"
android:padding="5dp"/>
Below is how I am populating the TableRow and the TextView:
for (int i = 0; i < result.length(); i++) {
final TableRow tr = (TableRow) getLayoutInflater(getArguments()).inflate(R.layout.result_table_row_light_theme, resultTable, false);
if (i == 0) {
tr.setBackgroundColor(getResources().getColor(R.color.appPrimaryColour));
} else if (i % 2 == 0) {
if (settings.getInt(Defines.SharedPreferenceSettings.APPLICATION_THEME,
com.BoardiesITSolutions.Library.R.style.LibAppTheme) == com.BoardiesITSolutions.Library.R.style.LibAppTheme) {
tr.setBackgroundColor(getResources().getColor(R.color.resultRowLightThemeAlternateRow));
}
}
JSONArray array = result.getJSONArray(i);
for (int j = 0; j < array.length(); j++) {
final TextView textView;
textView = (TextView) getLayoutInflater(getArguments()).inflate(R.layout.result_textview, tr, false);
textView.setText(array.getString(j));
if (i == 0) {
textView.setTypeface(null, Typeface.BOLD);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
tr.addView(textView);
}
});
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
resultTable.addView(tr);
}
});
}
If I change my TextView XML file so that the layout_width is wrap_parent instead of 0dp then everything is shown on the screen.
However, when the textview is 0dp and the layout_weight is 1 then nothing is displayed, however I would have expected each text view to be evenly distributed across the width of the screen to fill the space.
What I should probably mention, don't know if it makes a difference, is the TableView is within a HorizontalScrollView. The row should fit in the width of the screen, if the data is smaller than the screen, but if the row won't fit, then the view will be horizontally scrollable.
UPDATE 1
Below is the XML that hosts the TableLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="horizontal">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableLayout android:id="#+id/resultTable"
android:stretchColumns="*"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TableLayout>
</HorizontalScrollView>
</LinearLayout>
</ScrollView>
</RelativeLayout>

What I should probably mention, don't know if it makes a difference, is the TableView is within a HorizontalScrollView.
It is a logical error to tell a child view inside a scrolling container to match_parent or fill the available space in any way. A scrolling container, like ScrollView or HorizontalScrollView measures its one-and-only child view as UNSPECIFIED so that the child can grow beyond the parent bound in that one direction (and, thus, be scrollable).
The child of a scrolling container is not given what the "available space" would be for it to fill, and operations like layout weight have no effect if the parent's dimension is not well-defined.
The row should fit in the width of the screen, if the data is smaller than the screen, but if the row won't fit, then the view will be horizontally scrollable.
The functionality you are looking for is fillViewport (docs link), which tells the scrolling container to force the child to match it's size if the measured width (in the horizontal case) is less than the parent. Use this in place of applying a weight.

Try this :
public void createTextView(Context context, LinearLayout parent) {
final TextView v = new TextView(context);
parent.addView(v); // Mandatory!
v.post(new Runnable() { // In UI Thread. View Must be added to parent before getting layout params!
#Override
public void run() {
// Get params:
LinearLayout.LayoutParams lParams = (LinearLayout.LayoutParams) v.getLayoutParams();
// Set only target params:
lParams.width = 0;
lParams.weight = 1;
v.setLayoutParams(lParams);
}
});
}

Can you try to do your layout in XML (just to debug it, with dummy data)? Does it work as expected?
The docs mention that:
children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. TableRow always enforces those values to be respectively MATCH_PARENT and WRAP_CONTENT.
Not sure if that means that it'll also mess stuff up if you try to set these values. As you've found, it's clearly not just ignoring them if they are set.
The other part says that the parent of the TableRow should be a TableLayout - is that the type of resultTable (you mentioned TableView) - otherwise it will behave as a LinearLayout with horizontal orientation.

Related

How to show image in table row based on size

Have 2x2 grid(Dynamic using TableLayout) need to show image on that. now based on image size, means-- if image fit for 1 cell means 1 cell,else big means 2 cells or 4 cells based on size( I know how many cells it will occupy)
i can show image in 1 cell, but problem is if image need 2 cells(1st column) how can show image in 2cell(With out disturbing the grid)
Without disturbing the grid, the workaround I see is to dynamically set image on top of your TableLayout.
Then you can archive this:
I've uploaded the code of the test project here;
You initialize overlappingImage and once you need to set image to your cell - you just add it to the layout and setting height and width params based on number of cells you want to fill.
TableLayout generates dynamically, the cell's layout xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<View
android:layout_margin="4dp"
android:background="#aacc00"
android:layout_height="40dp"
android:layout_width="40dp"/>
</FrameLayout>
The Activity's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
android:padding="16dp"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TableLayout
android:id="#+id/tableLayout"
android:layout_width="match_parent"
android:layout_height="280dp"/>
<LinearLayout
android:id="#+id/buttonsLinearLayout"
android:layout_below="#+id/tableLayout"
android:layout_marginTop="16dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:text="1x1"
android:id="#+id/button11"
android:onClick="onClick11"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="4x1"
android:id="#+id/button21"
android:onClick="onClick41"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="2x3 at (2;2)"
android:id="#+id/button12"
android:onClick="onClick32"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="2x2"
android:id="#+id/button22"
android:onClick="onClick22"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
And the Activity code to handle button clicks & generates table:
public class MainActivity extends AppCompatActivity {
RelativeLayout container;
int cellWidth = 0, cellHeight = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.setStretchAllColumns(true);
for (int i = 0; i < 4; i++) {
TableRow tableRow = new TableRow(this);
for (int j = 0; j < 10; j++) {
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View cell = layoutInflater.inflate(R.layout.table_cell, null, false);
if (cellHeight == 0 ) {
cell.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
cellWidth = cell.getMeasuredWidth();
cellHeight = cell.getMeasuredHeight();
}
tableRow.addView(cell);
}
tableLayout.addView(tableRow);
}
container = (RelativeLayout)findViewById(R.id.container);
overlappingImage = new ImageView(this);
overlappingImage.setScaleType(ImageView.ScaleType.FIT_XY);
}
ImageView overlappingImage;
private void restoreTableLayout() {
container.removeView(overlappingImage);
}
public void onClick11(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth, cellHeight);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.horizontal_cat);
container.addView(overlappingImage);
}
public void onClick41(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth*4, cellHeight);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.horizontal_cat);
container.addView(overlappingImage);
}
public void onClick32(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth*3, cellHeight*2);
params.setMargins(cellWidth*2, cellHeight*2, 0 ,0);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.vertical_cat);
container.addView(overlappingImage);
}
public void onClick22(View view) {
restoreTableLayout();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(cellWidth*2, cellHeight*2);
overlappingImage.setLayoutParams(params);
overlappingImage.setImageResource(R.drawable.horizontal_cat);
container.addView(overlappingImage);
}
}
I hope, it helps.
Create separate layout files for rows that would need one cell and two cell as follows:
one_cell_table_row.xml (Notice the android:layout_span="2" for the ImageView
<?xml version="1.0" encoding="utf-8"?>
<TableRow
android:background="#drawable/bg_gray"
android:layout_marginTop="5dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/imgMyImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_span="2" />
</TableRow>
two_cell_table_row.xml (The TextView placed just as a placeholder for the second cell) (No layout_span required here as in the above layout)
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/imgMyImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_weight="1"
android:text="..."
android:textColor="#767575"
android:id="#+id/txtJustAPlaceholder"
android:textSize="14dp" />
</TableRow>
Note: The id for the ImageView to be kept same in both layout for the java code below to work correctly.
The above is assuming your grid is 2x2. If your grid size is different create more layout for each kind of row you want and add extra conditions in the java code below.
Adding the TableRow with the right layout inflated:
Then programatically determine which layout needs to be inflated. Inflate the required layout for table row and add it to your table layout:
Following code is assuming that you are using a fragnemt. If you are doing directly in an activity replace code to work for Activity accordingly.
TableLayout table = (TableLayout) getView().findViewById(R.id.youtTableLayout);
if(<your image size needs two cells>) {
TableRow row = (TableRow) LayoutInflater.from(getActivity().getApplicationContext())
.inflate(R.layout.two_cell_table_row, null);
}
else if(<your image size needs one cell) {
TableRow row = (TableRow) LayoutInflater.from(getActivity().getApplicationContext())
.inflate(R.layout.one_cell_table_row, null);
}
...
...
// add more conditions and respective layouts as you need.
...
...
ImageView myImgView = (ImageView) row.findViewById(R.id.txtCrdSectionHeader);
// set the image for your image view here.
table.addView(row);
table.requestLayout();
Again, the above was assuming that your TableLayout has a 2x2 grid. If you plan to use a different one, update the layout files for TableRows we created above accordingly or set them dynamically using your java code.
You can calculate the image size and the screen size at runtime.Based on the calculations you can set the table properties at runtime. For example if the image is going to take two columns set the span property on that row programmatically.
I would suggest for your requirement you can consider creating the layout in code itself-rather than using any xml.
You can also have a look at Recycler view. It has more powerful ways to control the layout of the children. Have a look at this video-Mastering Recycler View -It is trying to do similar thing what you are looking for.

How to split Linear Layout in to two columns?

I have to split a Single Linear layout into a Two Columns(Like newspaper Columns).The linear layout contain text-view and image-view
I have taken the screen width and have divided it to half and made the TextView and ImageView to come in a first column , ie, A B C blocks in the picture below.. now the remaining TextView and 'ImageView has to go to next column like in D E F like that it goes on.So it would be helpful if anyone gives me any code or ideas to implement this.. I tried with GridView which is not suitable for my issue. Since the TextView and ImageView sizes are not definite.
I don't know how to split Liner layout.
I tried with calculating the rootlayout height
like this
linearLayout.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
int linsize=linearLayout.getHeight();
int relsize=root.getHeight();
int textsize=txt1.getHeight();
mainheight=relsize;
subheight=linsize;
Toast.makeText(getApplicationContext(), "Linerlayout "+linsize, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "Relative layout"+relsize, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "text height "+textsize, Toast.LENGTH_LONG).show();
if(mainheight==subheight)
{
Toast.makeText(getApplicationContext(), "make a new linear layout", Toast.LENGTH_LONG).show();
createsubview();
}
}
});
Screenshot
You could easily do this with nested LinearLayouts:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/item" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<ImageView
content here/>
<TextView
content here/>
</LinearLayout>
</LinearLayout>
Then all that you need to do is put A, B and C in the first vertical layout, and D, E and F in the second.
You can't do it with GridView. You would have to create a custom view to do this.
if you know how big your grid items are, you can cut some corners. GridView is complicated mostly because it deals with items of any size and loads them dynamically. An easier way for you might be:
1.Create a HorizontalScrollView with a horizontal LinearLayout inside.
2.Determining how many rows of your item will fit on the screen. Call this rows.
3.while you still have items you need to layout:
1.Create a vertical LinearLayout, adding rows or less items to it.
2.Add your new vertical LinearLayout to the horizontal one.
There are some downsides versus what a "horizontal GridView" would get you:
1.All the views are loaded up immediately, which is bad for huge lists of items.
2.You need to know how big your items are, and they need to be the same size.
Upsides:
1.It's very easy to implement.
for more inf plz see this link
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScrollView scrollView = new ScrollView(this);//ScrollView
LinearLayout ll = new LinearLayout(this); //root LinearLayout
ll.setOrientation(LinearLayout.HORIZONTAL);//with horizontal orientation
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT,1f);
LinearLayout l2 = new LinearLayout(this); //sub linearlayout
l2.setOrientation(LinearLayout.VERTICAL);//with vertical orientation
l2.setLayoutParams(layoutParams);
LinearLayout l3 = new LinearLayout(this); //sub linearlayout
l3.setOrientation(LinearLayout.VERTICAL);//with vertical orientation
l3.setLayoutParams(layoutParams);
int totalvalues=41; //i take count as 41
for(int i=0;i<totalvalues;i++){ // add the buttons in the layout based on condition
Button okButton=new Button(this);
okButton.setText("Button"+i);
if(i<=totalvalues/2){
l2.addView(okButton);
}
else{
l3.addView(okButton);
}
}
ll.addView(l2); //add sub linearlayout to root linearlayout
ll.addView(l3); //add sub linearlayout to root linearlayout
scrollView.addView(ll); //add the root linearlayout to scrollview
setContentView(scrollView);
}
Have you tried:
DisplayMetrics metrics = getResources().getDisplayMetrics();
float dpW = 0f;
int pixelsW = (int) (metrics.density * dpW + 0.5f);
TableLayout.LayoutParams lp = new TableLayout.LayoutParams(pixelsW, LayoutParams.WRAP_CONTENT, 1f);
TextView txt = new TextView(MainActivity.this);
ImageView img = new ImageView(MainActivity.this);
txt.setLayoutParams(lp);
img.setLayoutParams(lp);
Using TableLayout's LayoutParams, you can set the weight of the view, which, as you know, must be 1. We also use DisplayMetrics to convert a float into the "dp" format used in xml.
EDIT:
You can also set this LayoutParams to a LinearLayout.

Add a scrollbar to a dynamic view

I have a LinearLayout and I amdynamically creating a certain number of TextViews in it.
Sometimes there are more TextViews than fit on the screen.
How do I add a scrollbar to this view, so the user can scroll up and down and see all TextViews?
Here's part of my code:
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
for (int n = 0; n < (numberOfPlayers*(numberOfPlayers-1)/2); n++) {
TextView tv = new TextView(this);
tv.setText(gamelist[n][0] + " - " + gamelist[n][1]);
layout.addView(tv);
}
Include your linearLayout in a ScrollView
<ScrollView
android:id="#+id/scroll"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<LinearLayout ... />
</ScrollView>
Note that a ScrollView can only have one view child
Wrap your LinearLayout into a ScrollView.
In this case you may consider using a ListView (tutorial here).

How do I calculate the required height of a GridView that is inside of a ScrollView on Android?

I have a GridView inside of a LinearLayout inside of a ScrollView that pages in data from the server. Beneath the GridView is a button to load more data. My GridView will have an ultimate height that is larger than the screen. If I set the height of my GridView to either wrap_content or parent_fill, it sizes itself to the exact available on-screen height and does not scroll at all, cropping out the extra rows. If I explicitly set the layout_height to something large, like 1000dip, scrolling behaves properly, however I cannot predict the final height of my scroll view apriori.
How do I programmatically determine the necessary height of a GridView to get the desired behaviour?
Here is my layout below. As you can see I set the height to 1000dip, but that is bogus, I need that value to get set automatically/programmatically:
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:layout_weight="1"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="1000dip"
android:columnWidth="70dp"
android:numColumns="auto_fit"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:background="#000000"
android:layout_weight="1"
/>
<Button
android:id="#+id/load_more"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Load More Foo"
/>
</LinearLayout>
</ScrollView>
Here is one way to do this, if someone needs it. A bit of a hack but does the trick. You have to set GridView initially big enough for all the views (e.g. 10000dip)
final GridView imageContainer = // your GridView
imageContainer.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
imageContainer.getViewTreeObserver().removeGlobalOnLayoutListener( this );
View lastChild = imageContainer.getChildAt( imageContainer.getChildCount() - 1 );
imageContainer.setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, lastChild.getBottom() ) );
}
});
I know it's an old case, but I had a similar problem where my ScrollView contained multiple LinearLayouts, which in their turn contained a header and a GridView.
Basically I made categorised sections with headers containing images belonging to that category.
The GridView had to have a flexible height.
I found a lot of answers about overriding onMeasure(), but it worked only on some devices, not all. The height would eventually be 1, or 3 or just 0, displaying only a few pixels of the image.
StretchingGridView class
I overrode the drawableStateChanged() method with this code, inspired by #Karitsa's solution:
#Override
public void drawableStateChanged() {
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
getViewTreeObserver().removeOnGlobalLayoutListener( this );
View lastChild = getChildAt( getChildCount() - 1 );
if (lastChild != null) {
int height = Math.max(lastChild.getBottom(), getColumnWidth());
float child = getAdapter().getCount();
float col = getNumColumns();
int rows = (int) Math.ceil(child / col);
height = rows * getColumnWidth() + (getHorizontalSpacing() * rows-1);
setLayoutParams( new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, height ) );
}
}
});
}
Note: My GridView uses square images, so I base the height on their width. I don't think it works well with flexible grid item heights.
Apparently GridViews inside ScrollViews are not kosher in Android-land. Switching to ListView with custom-made rows. That seems to behave better.

How can I get an Android TableLayout to fill the parent in landscape mode?

I am using a TableLayout in my application. It contains four TableRows each containing four ImageViews. The behavior I want is to scale the layout to fit the shortest dimension.
It works fine in portrait mode but fails miserably in landscape mode.
From the documentation it looks like this is because the TableRow layout_height is always set to WRAP_CONTENT. While I can set the dimensions of the individual Views, the TableLayout won't render at all if I set the View layout_height to FILL_PARENT.
I feel like there is something simple I am missing. Is there a way to get the TableLayout with TableRows to scale to fit the height in landscape mode?
XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/table"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:shrinkColumns="*">
</TableLayout>
Java:
public class Example extends Activity {
private TableLayout mTable;
private int[] mDrawableIds = { R.drawable.draw01, R.drawable.draw02, R.drawable.draw03, R.drawable.draw04, R.drawable.draw05, R.drawable.draw06, R.drawable.draw07, R.drawable.draw08, R.drawable.draw09, R.drawable.draw10, R.drawable.draw11, R.drawable.draw12, R.drawable.draw13, R.drawable.draw14, R.drawable.draw15, R.drawable.draw16 };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTable = (TableLayout)findViewById(R.id.table);
for (int j=0; j<4; j++) {
TableRow tr = new TableRow(this);
tr.setLayoutParams(new ViewGroup.LayoutParams( LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
for (int i=0; i<4; i++) {
ImageView iv = new ImageView(this);
iv.setImageResource(mDrawableIds[j*4+i]);
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setAdjustViewBounds(true);
tr.addView(iv);
}
mTable.addView(tr);
}
}
}
Change your XML layout to:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/table"
android:layout_width="fill_parent"
android:layout_height="160dp"
android:shrinkColumns="*">
</TableLayout>
That should make it take up whole screen's height regardless of orientation. See density independent pixels
I did figure out how to do this. Basically, the part that wasn't working the way I wanted was the TableRows. When I changed to landscape, the first two TableRows weren't resizing at all and the third was consuming the remainder of the space. The fourth row wasn't displaying at all.
I figured out that I needed to set the layout_weight of the TableRows to equal values. But, there is no method to do that at runtime, so I built the following layout file, which I called row.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/trow"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1">
</TableRow>
Then I used a LayoutInflater to build the row at runtime with the properties I wanted:
mTable = (TableLayout)findViewById(R.id.table);
LayoutInflater inflater = getLayoutInflater();
for (int j=0; j<4; j++) {
View row = inflater.inflate(R.layout.row, mTable,false);
TableRow tr = (TableRow)row.findViewById(R.id.trow);
for (int i=0; i<4; i++) {
View image = inflater.inflate(R.layout.image, tr, false);
ImageButton ib = (ImageButton)image.findViewById(R.id.image);
ib.setAdjustViewBounds(true);
ib.setImageResource(mCardIds[j*4+i]);
tr.addView(ib);
}
mTable.addView(tr);
}
Now the TableRows are resizing properly on rotation. I changed the ImageViews to ImageButtons because I decided to add some onClick behavior and I am building those buttons via a separate xml file, but I don't think those details are relevant to the resizing issue.
I tried the accepted solution here but it did not work. What worked is as below:
TableRow tr = new TableRow(this);
TableLayout.LayoutParams pRowTop = new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT);
pRowTop.weight = 1;
mTable.addView(tr, pRowTop);

Categories

Resources