I'm using a TableLayout to create a square gameboard in Android. I want to set the dp of the table's width and height, and have its contents automatically expand and contract to fit the table.
I got this working with the entries in the tableRows as LinearLayouts with a single ImageView inside, but I need to change what images are displayed with click actions, so I thought I would use a ViewFlipper.
Now that I'm using the ViewFlipper, though, my image sizes have gone all wonky. Does anyone know if there's a setting I can set on ViewFlipper to get the images to auto adjust their size in a table?
Here's my xml:
<TableLayout
android:id="#+id/gameBoard"
android:layout_width="#dimen/boardWidth"
android:layout_height="#dimen/boardWidth"
android:layout_margin="0dp"
android:padding="0dp"
android:shrinkColumns="*"
android:stretchColumns="*" >
</TableLayout>
And here's the code I'm programmatically creating the table with:
TableLayout gameBoard = (TableLayout) findViewById(R.id.gameBoard);
TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
rowParams.setMargins(0, 0, 0, 0);
for (int y = settings.getBoardSide() - 1; y > -1; y--) {
TableRow row = new TableRow(this);
row.setPadding(0, 0, 0, 0);
for (int x = 0; x < settings.getBoardSide(); x++) {
ViewFlipper flipper = new ViewFlipper(this);
flipper.setOnClickListener(new TileClick());
//default image
ImageView cloud = new ImageView(this);
cloud.setImageResource(R.drawable.transparent_cloud);
cloud.setAdjustViewBounds(true);
flipper.addView(cloud, 0);
//second image
ImageView landscape = new ImageView(this);
landscape.setImageResource(R.drawable.land_scape);
landscape.setAdjustViewBounds(true);
flipper.addView(landscape, 1);
row.addView(flipper);
}
gameBoard.addView(row, rowParams);
}
It turned out that for my purpose a FrameLayout with its width and height set to a specific dp was best. That way I can control the view and ensure it has the right height and width. With the FrameLayout I can add and remove views at will, and layer different views on top of each other as well.
Related
I am trying to add many button into Relativelayout or Linearlayout,
Layout
<Relativelayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
>
</Relativelayout>
then in the class
_ll_layout = (RelativeLayout) findViewById(R.id.container);
I only know how add the button dynamically with code.
JSONArray jsonArray = new JSONArray(tmp.getString("productos"));
Button bt[] = new Button[jsonArray.length()]; // size of product
for (int i = 0; i < jsonArray.length(); i ++){
int padding_40dp = (int) (40 * scale + 0.5f);
int margin_10dp = (int) (10 * scale + 0.5f);
int padding_90dp = (int) (90 * scale + 0.5f);
LinearLayout.LayoutParams params = new Relativelayout.LayoutParams(padding_90dp, padding_40dp);
params.setMargins(margin_10dp, 0 , 0, 0);
bt[i] = new Button(DetalleServicioActivity.this);
bt[i].setText(jsonArray.getJSONObject(i).getString("nombre"));
bt[i].setTag(new TagInfo(jsonArray.getJSONObject(i).getString("id_producto")));
bt[i].setTextColor(Color.parseColor("#FFFFFF"));
bt[i].setBackgroundColor(Color.parseColor("#D8D8D8"));
bt[i].setEnabled(false);
bt[i].setId(Integer.parseInt(jsonArray.getJSONObject(i).getString("id_producto")));
bt[i].setLayoutParams(params);
_ll_layout.addView(bt[i]);
}
but the result is
One on another one, but I need something like this:
Edit
If I use LinearLayout with orientation horizontal and gravity center, this happend
Instead of using Relative Layout or Linear Layout I would rather suggest you to create custom flow layout.Custom flow layout will adjust child views accordingly in rows, and will jump the button in new row according to screen width.
Please have a look here : Flow layout example
Happy Coding :)
Instead of RelativeLayout, make use of LinearLayout with orientation as horizontal and add the button in them at run time
As per your design requirement, make sure you have two linear layouts here.
you can use griedlayout for solved your problem
Hey I have a grid of ImageButtons that is being scaled by display width and contains a PNG file as image. I add the whole thing to the linear layout like this:
public void createButtons(){
int buttonX = 9;
int buttonY = 9;
int size = 80;
int tag = 0;
TableLayout layout = new TableLayout (this);
layout.setLayoutParams( new TableLayout.LayoutParams(900,900) );
layout.setPadding(1,1,1,1);
layout.setBackgroundColor(0xff00af00); //green
RelativeLayout ll = (RelativeLayout)findViewById(R.id.rel);
ll.addView(layout);
for(int x=0;x<buttonX;x++) {
TableRow tr = new TableRow(this);
for(int y=0;y<buttonY;y++) {
but[x][y] = new ImageButton(this);
but[x][y].setBackgroundColor(0xff0000af); //blue
but[x][y].setImageResource(R.drawable.buttonmask3);
but[x][y].setScaleType(ImageButton.ScaleType.CENTER_INSIDE);
tr.addView(but[x][y], height/10,height/10);
}
layout.addView(tr);
}
}
The problem is, that the layout now looks like the following:
whereas it is supposed to look like:
(this one was a quick photoshop but you get the idea, that the scale is supposed to fill the button completely)
What can I do about these tiny images? I tried CENTER_INSIDE, FITXY and all the other ScaleTypes but I haven't been lucky so far :/
The width is taken from the screen width (or height in landscape)
the buttonmask3.png is about 170*170 px.
The problem is the padding that the ImageButton comes with naturally.
adding
but[x][y].setPadding(0, 0, 0, 0);
along with
but[x][y].setScaleType(ImageButton.ScaleType.CENTER_CROP);
Solved it for me.
I need to show the TextViews based on the info received from a server. E.g. I got 7 words from the server . I need to put every word in a different TextView to make it clickable. The textviews should fill the screen of the device from left to right in the lines. When the right border is reached then the next TextViews should be placed on the next line and so on.
The quantity of TextViews is variable and the words in the Textviews is different as well.
Create new textView instance and setLayoutparams to them.
Example,
TextView[] tx = new TextView[10];
TableRow[] tr = new TableRow[10];
for(i=0; i<10; i++) {
tx[i] = new TextView(this);
tx[i].setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tx[i].setText("Data")
tr[i] = new TableRow(this);
tr[i].setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tr[i].addView(tx[i]);
// and then adding table row in tablelayout
}
For your problem you can use single textview and set spannable string to the textview.
Within that string you can provide clicks you want.
I found the solution.
I won't put the whole code here. Only main parts.
There is vertical LinearLayout.
We need to calculate the width of the layout. I couldn't do it because I do all calculations before it is drawed.
I'm getting the screen width in dips:
Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
float density = getResources().getDisplayMetrics().density;
float dpWidth = outMetrics.widthPixels / density;
int displayWidth = (int) dpWidth;
This is the free space available to put the Textviews.
Add LinearLayout to parent. Create a Textview and calculate the width:
// Calculate size of the button
Rect bounds = new Rect();
Paint textPaint = menuCategoryTV.getPaint();
textPaint.getTextBounds(text, 0, text.length(), bounds);
int width = bounds.width();
Then check if there is a room to place the Textview in the layout. To get it deduct TextView's width from available free space on the screen. Of course there is a space for the first textView. Until your TextView is not very long. But after filling up the layout by TextViews there will be no room for new elements. Create new LinearLayout, add it to parent and reset availble room to initial value.
I have a xml view that contains a ScrollView(with a child LinearLayout).
...
<ScrollView
android:id="#+id/scrollView_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_marginTop="33dp" >
<LinearLayout
android:id="#+id/image_holder"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</LinearLayout>
</ScrollView>
...
I am trying to dynamically add some images, I want 3 per row.
private void createDice(LinearLayout ll, Integer required) {
ArrayList<Integer> images = new ArrayList<Integer>();
images.add(R.drawable.one);
images.add(R.drawable.two);
images.add(R.drawable.three);
images.add(R.drawable.four);
images.add(R.drawable.five);
images.add(R.drawable.six);
ScreenHelper screen = new ScreenHelper(MainActivity.this);
Map<String, Float> s = screen.getScreenSize();
Integer maxPerRow = (int) (s.get("width") / 90); // images are 89px wide
Log.d(TAG, "max across::"+maxPerRow);
Integer rows = (required / maxPerRow);
Log.d(TAG, "rows::"+rows);
for (int i=0; i < rows; i++) {
Log.d(TAG, "i::"+i);
// create linear layout for row
LinearLayout llAlso = new LinearLayout(this);
llAlso.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
//llAlso.setOrientation(LinearLayout.HORIZONTAL);
for (int j=0; j < 3; j++) {
Log.d(TAG, "j::"+j);
// create/add image for the row
ImageView iv = new ImageView(this);
iv.setImageResource(images.get(i));
llAlso.addView(iv);
}
// add to main layout
ll.addView(llAlso, i);
Log.d(TAG, "adding to main view");
}
}
I am testing with the required parameter value of 6.
The problem is that the first row of images gets added, but either the second isn't because it is getting added adjacent to the first row (and therefore off the screen) and not under it.
How to achieve my desired output?
Set the orientation in your image_holder layout to vertical. By default, the orientation of a LinearLayout is horizontal. That means that all child views will be added in a horizontal row. Since your child layouts use fill_parent for their width, only one child can fit in the row. By switching it to vertical, your layouts are added in a vertical column instead of in a row. That allows more layouts to be visible.
Also you should consider to use a GridLayout instead. That is made for exactly this case.
On my code i need to create some table that each column contain Bitmap and text - and i create this table dynamically.
So i doing this by using this code:
for (int i = 0; i < collection.size(); i++)
{
ObjectITem item = collection.get(i);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView textView = new TextView(this);
textView.setText(item.getText());
linearLayout.addView(textView);
linearLayout.addView( (new ImageButton(this)).setImageBitmap(item.getBitmap());
layout.addView(linearLayout, LayoutParams.WRAP_CONTENT);
}
this code is working good - but because the originaly images are not in same size - i see that the images that appear on the ImageButton are look not good.
How can i make all the images on the ImageButton to look the same ?
Is there some better way to make the layout that i did here ?
1) You can use Bitmap.createScaledBitmap() to scale all the images to a desired size. Like this...
Bitmap buttonBmp = Bitmap.createScaledBitmap(item.getBitmap(), buttonW, buttonH, true);
linearLayout.addView((new ImageButton(this)).setImageBitmap(buttonBmp);
2) You might want to consider using a ListActivity and a ListView. This is more complicated, but may be more efficient if your collection is large and needs to scroll over many pages.