I've seen non-scrollable ScrollView's a few times on stackoverflow.com, but none of the proposed solutions work for me. Ihope someone can help.
I have a ScrollView containing a TableLayout. The TableLayout is empty, but I programmatically insert rows and columns. I am guessing that I need to tell the ScrollView that the TableLayout has changed/updated, and ScrollView needs to recalculate if it needs to enable scrolling.
I tried to invalidate both the ScrollView and the TableLayout, I tried requestLayout(), but nothing seems to do anything. What am I missing?
Here is my layout XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:scrollbars="horizontal|vertical" >
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stretchColumns="*"
android:id="#+id/maintable" >
</TableLayout>
</ScrollView>
And here is my Java code. Basicly, this code adds a row per player and 25 buttons next to each player. The buttons are there, but they are out of the screen boundaries.
// Get the TableLayout
TableLayout tl = (TableLayout) findViewById(R.id.maintable);
// Go through each item in the array
for (int player = 0; player < players.length; player++)
{
// Create a TableRow and give it an ID
TableRow tr = new TableRow(this);
tr.setId(100+player);
tr.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
// Create a TextView to add the player name
TextView labelTV = new TextView(this);
labelTV.setId(200+player);
labelTV.setText(players[player]);
//labelTV.setTextColor(Color.BLACK);
labelTV.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tr.addView(labelTV);
// numShots = 25
for (int shot = 0; shot < numShots; shot++)
{
Button shotButton = new Button(this);
shotButton.setId((player * 100) + shot);
shotButton.setText(Integer.toString(shot));
tr.addView(shotButton);
}
tl.addView(tr, new TableLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
// Add the TableRow to the TableLayout
//};
}
I think you're needing a horizontal scroll? ScrollView only does vertical scrolling, you'll need to have a look at HorizontalScrollView.
Related
I want that the buttons had identical sizes and table was fully filled the buttons. But the buttons have a different size, what do I wrong in?
My xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background"
android:orientation="horizontal" >
<LinearLayout
</LinearLayout>
<TableLayout
android:id="#+id/mainTableL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="40dp" >
</TableLayout>
</LinearLayout>
My code:
layoutParams = new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f);
mainTableLayout = (TableLayout) findViewById(R.id.mainTableL);
tableRow = new TableRow[VALUE_ROWS];
btn = new Button[VALUE_ROWS*VALUE_COLUMNS];
for (int indexRow = 0; indexRow < VALUE_ROWS; indexRow++){
tableRow[indexRow] = new TableRow(this);
tableRow[indexRow].setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f));
for (int indexColumn = 0; indexColumn < VALUE_COLUMNS; indexColumn++){
btn[countBtn] = new Button(this);
btn[countBtn].setLayoutParams(layoutParams);
btn[countBtn].setId(countBtn);
btn[countBtn].setBackgroundResource(R.drawable.fon);
tableRow[indexRow].addView(btn[countBtn],layoutParams);
countBtn++;
}
mainTableLayout.addView(tableRow[indexRow], layoutParams);
}
I am sorry for my pure english.
Thank you
I'm not sure if changing this will help you, but this definitely should be fixed. For table rows you should set TableLayout.LayoutParams instead of TableRow.LayoutParams:
tableRow[indexRow].setLayoutParams(new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f));
and later when you add a row, don't specify layoutParams:
mainTableLayout.addView(tableRow[indexRow]);
Also note that specifying size for rows doesn't have any effect, their width is set to MATCH_PARENT and the height - to WRAP_CONTENT (see the doc). And similar with buttons, TableRow sets their width to WRAP_CONTENT and the height - to MATCH_PARENT regardless of what you specify in the layout params.
I have a TableLayout inside a HorizontalScrollView. When I add a single row of images, the images are side by side, no extra padding.
But when I add another row, and the images scale down, the TableLayout creates extra padding horizontally around each cell, but not vertically.
Here is my code:
TableLayout grid = (TableLayout) deckBuilder.findViewById(R.id.grid);
for (int j = 0; j < 3; ++j) {
TableRow testRow = new TableRow(this);
\\Each row has the same weight
testRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.MATCH_PARENT, 1f));
for (int i = 0; i < 20; ++i) {
ImageView testImage = new ImageView(this);
testImage.setImageResource(R.test_image);
testRow.addView(testImage);
}
grid.addView(testRow);
}
And here is my xml:
<HorizontalScrollView
android:id="#+id/horizontalscroll"
android:layout_width="wrap_content"
android:layout_height="1dip"
android:scrollbars="none"
android:overScrollMode="never">
<TableLayout
android:id="#+id/grid"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</TableLayout>
</HorizontalScrollView>
Edit:
Sorry mis-read the code.
Solution:
set the width/height of your image views to wrap_content. You do this via the
LayoutParams object:
http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html
See this question for an example:
Show ImageView programmatically
//ImageView Setup
ImageView imageView = new ImageView(this);
//setting image resource
imageView.setImageResource(R.drawable.play);
//setting image position
imageView.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
Look at the docs here:
http://developer.android.com/reference/android/widget/ImageView.html
Specifically look at scaleType:
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
I think one of the options there should resolve this (maybe...fitXY?)
I have a small app that periodically needs a table row added to the tablelayout. Per the getChildCount() method the row is being added but it doesn't display. Any suggestions would be greatly appreciated
TableLayout tbl = (TableLayout)findViewById(R.id.mytbl);
TableRow row = new TableRow(this);
LinearLayout ll = new LinearLayout(this);
TextView txtView = new TextView(this);
row.setId(1234);
row.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,TableRow.LayoutParams.WRAP_CONTENT));
row.setGravity(Gravity.CENTER);
row.setBackgroundResource(android.R.color.darker_gray);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT,1.0f);
ll.setId(1589);
ll.setLayoutParams(lp);
ll.setOrientation(LinearLayout.VERTICAL);
ll.setBackgroundResource(R.color.header_background);
ll.setGravity(Gravity.CENTER);
String msg = "Sample Text";
txtView.setId(657);
txtView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
txtView.setTextColor(R.color.a_color);
txtView.setBackgroundResource(R.drawable.border_a);
txtView.setGravity(Gravity.TOP | Gravity.LEFT);
txtView.setText(msg);
ll.addView(txtView);
row.addView(ll);
tbl.addView(row,new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));//maybe add this with layout params tl.addView(tr,new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
i've tried tbl.RequestLayout() and tbl.Invalidate() but no help. The table is wrapped in a scrollview which is my best guess as to where the problem is. I've been tinkering with this for several hours so a nudge in the right direction sure would be helpful
<ScrollView
android:id="#+id/scrVw_lst"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TableLayout
android:id="#+id/mytbl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="*">
Have you run the code for adding a row in your TableLayout? I've simulated adding a row on a click of a Button and I get a awkward Divide by 0 exception.
Anyway, change the LayoutParams of the enclosing Linearlayout to TableRow.LayoutParams(its parent is the TableRow):
TableRow.LayoutParams lp = new TableRow.LayoutParams(
TableRow.LayoutParams.FILL_PARENT,
TableRow.LayoutParams.WRAP_CONTENT, 1.0f);
ll.setId(1589);
ll.setLayoutParams(lp)
Also, if this doesn't solve the problem, try to add:
android:fillViewport="true"
to the ScrollView tag in the xml layout.
An activity in my application (my first attempt at one) generates several table rows each containing a couple of EditTexts and a Button. But, the button always appears to be misaligned, resulting in this problem - the delete buttons are shifted slightly downwards.
The relevant part of the xml layout is as follows:
<ScrollView
android:id="#+id/countEditList"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableLayout
android:id="#+id/countEditLayout"
android:stretchColumns="*"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- insert the new rows here as they are created -->
</TableLayout>
</ScrollView>
The code which creates each row from a database cursor does the following:
TableRow row = new TableRow(this);
EditText title = new EditText(this);
title.setHorizontallyScrolling(true);
title.setGravity(Gravity.CENTER);
title.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
EditText counting = new EditText(this);
counting.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
counting.setGravity(Gravity.CENTER);
Button deleteCount = new Button(this);
deleteCount.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
deleteCount.setText(R.string.deleteCount);
deleteCount.setOnClickListener(this);
deleteCount.setGravity(Gravity.CENTER);
row.addView(title);
row.addView(counting);
row.addView(deleteCount);
layout.addView(row,new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); // Earlier: layout = (ViewGroup) findViewById(R.id.countEditLayout);
I suspect that I should somehow be setting the layout_gravity of the EditTexts and Button but I can't work out how to do that - would anyone be able to offer any suggestions?
You could adjust Edit Texts positioning using some padding:
title.setPadding(3, 3, 3, 3);
counting.setPadding(3, 3, 3, 3);
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);