I have a linearlayout on xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rootlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
And I add dynamic 100 textviews inside it by code below:
llayout = (LinearLayout) findViewById(R.id.rootlayout);
for (int i = 0; i < 100; i++) {
TextView tv = new TextView(this);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
int randomInt = new Random().nextInt(100) +1 ;
tv.setText(""+randomInt);
llayout.addView(tv);
}
The result is 100 textviews added and display vertically. This is not as my expect. I want these textviews display with random position inside the layout look like the image below:
How to do it? Thank you!
LinearLayout is for layouting its children linearly (as the name suggests).
As there is no RandomLayout, you can use a RelativeLayout with random left and top layout margins, or an AbsoluteLayout and set random x and y.
Edit: Avoid overlapping texts
Random positions can of course lead to overlapping and it would be up to you to adjust the positions or ignore positions too similar to previous ones. Or you might actually compare the bounding boxes (left, top, width, height) of the view you're about to add to all other views in the container and if there is any overlapping, find another place for it.
You can use tv.setX(position) and tv.setY(position) for show view on specific position
Related
I need to generate TextView inside a layout from a random, API generated, ArrayList. I cant seem to find a way in which they appear in one line, like a String, one after the other and also shift below once the line has reached the max layout width limit. I want each TextView to be sperate as I want to click them.
Would like to achieve something like this...
This is the current code but the line stops and I don't know how to shift it below. Currently I am using a relative layout as the base layout but it is not necessary.
for (int i = 0; i < abc.size(); i++) {
titleText = new TextView(this);
titleText.setId(i);
titleText.setText(abc.get(i));
relativeLayout.addView(titleText, i);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 10, 10, 10);
layoutParams.addRule(RelativeLayout.RIGHT_OF, titleText.getId() - 1);
titleText.setLayoutParams(layoutParams);
titleText.setTextColor(getResources().getColor(R.color.teal_700));
tvArray.add(titleText);
}
Example
In your xml
<LinearLayout
android:id="#+id/my_ll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
And write code in yourjava.class
LinearLayout my_ll = (LinearLayout) findViewById(R.id.my_ll);
for(int i=0;i<your_number_of_textviews;i++)
{
TextView text = new TextView(this);
text.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
text.setText(""+i);
my_ll.addView(text);
}
I think this solution would have solved it. First before the loop retrieve somewhere the width of the screen by using -
Point screenSizePoint = new Point();
// this gives you the furthest point from 0,0 e.g. 1440x3168
getWindowManager().getDefaultDisplay().getSize(screenSizePoint);
int sum = 0;
Then you retrieve your abc list somewhere.
And then you always compute the width of the current TextView by using this
titleText.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int width = titleText.getMeasuredWidth();
sum += width;
if (sum >= screenSizePoint.x) {
// shift to next line
}
and sum it up with the width of text views placed before and if the width is bigger than the screen width you just begin on another line.
I want to place some images (triggered on click action) inside a layout. I have to place them such that they don't get out of the parent layout.
Code I'm using to add a new image on clicking the layout:
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
ImageView image = new ImageView(this);
LinearLayout.LayoutParams coordinates = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
image.setLayoutParams(coordinates);
image.setImageResource(R.drawable.image);
layout.addView(image);
If I press on the layout , I must see my imageView put randomly.
Random random = new Random();
int x = random.nextInt(layout.getWidth());
int y = random.nextInt(layout.getHeight());
image.setX(x);
image.setY(y);
But this won't do it. And I see those images outside my layout too.
You are setting x & y which are upper left-top corner - starting point of image to display it. As x/y value can be right/bottom corner, therefore, your image goes out of layout in that case.
Please note - x, y are starting point from where your image will be drawn.
You need to make sure that layoutWidth - x >= imageWidth and layoutHeight - y >= imageHeight.
I have a trouble while creating a kind of view. Let's just say that i'm trying to create something similar to a clock. This means that we have to position numbers in a distance and angle from a center.
I tried to emulate a way to position two elements. A center ImageView and a clock number. In XML I have something similar to:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lyt_rootView"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/ivCenter"
android:background="#drawable/cid"/>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/ivNumber"
android:background="#drawable/add_big"
android:layout_marginLeft="-50dp"
android:layout_marginTop="50dp"/>
</RelativeLayout>
And it works pretty well, the images set as they should be, being completly centered the first image (ivCenter) and taking some margin from the center for positioning the second image.
Now I have to do the same programatically so I can create lots of imageViews simulating the numbers. So I have this code:
RelativeLayout lyt = (RelativeLayout) findViewById(R.id.lyt_rootView);
int avatarSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 70, getResources().getDisplayMetrics());
int distance = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
// center image
ImageView ivImageCenter = new ImageView(this);
ivImageCenter.setImageResource(R.drawable.cid);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(avatarSize,avatarSize);
lyt.addView(ivImageCenter, lp);
// first image (simulating a number in a clock)
ImageView ivNumber1 = new ImageView(this);
ivNumber1.setImageResource(R.drawable.add_big);
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(avatarSize,avatarSize);
lp2.setMargins(distance, distance, 0, 0);
lyt.addView(ivNumber1, lp2);
but the result is not similar as the XML example. I don't see what I'm missing. The result of creating the views programatically is that the two imageViews are trying to position in a center space in the screen making the first image not centered to the screen.
What I'm missing?
Finally I solved it by creating a one pixel layout centered in XML that acts as a reference and programatically adding the views in that reference view.
I have an app under construction. In one of the sub-menus I have a need for generic display of buttons, and therefor I want to make an activity that can display the given number of needed buttons.
I have succesfully made this happen, programmatically, but I want the total grid of buttons to fill up the entire parent they are placed in, which happens to be 3/4 of a landscape screen. The number of buttons varies from 16-38.!
I have also succesfully made this happen with other grids of buttons, in xml, with weight values, and match_parent values of entries.
When I assign buttons or rows the match_parent value programatically, it occupies the entire parent layout, not sharing it like i expect it to do, even though they have the same weight value of 1.0f
The relevant code follows below. I would like to post images as well, but I have not the reputation to do so.
`LinearLayout layout = (LinearLayout) findViewById(R.id.linear_custom_draw);
layout.setOrientation(LinearLayout.VERTICAL);
int columns = Math.min(6, 4+category); //sets number of buttons per row to 4-6
for (int i = 0; i < 4+category; i++) {
LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new android.view.ViewGroup.LayoutParams(android.view.WindowManager.LayoutParams.MATCH_PARENT,
android.view.WindowManager.LayoutParams.MATCH_PARENT));
//the line above is the line that fills up the entirety of the linearlayout, even though there are more entries, unlike my xml-defined attempts.
row.setOrientation(LinearLayout.HORIZONTAL);
row.setWeightSum(1.0f);
if(i%2 == 0){
row.setBackgroundColor(getResources().getColor(R.color.listview_red_backgr_color));
}
for (int j = 0; j < columns; j++) {
int index = (i*columns)+j;
if(formations.size() > index){
Button btnTag = new Button(this);
btnTag.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
btnTag.setText(formations.get(index).getName());
btnTag.setTextColor(getResources().getColor(R.color.black_overlay));
btnTag.setId(formations.get(index).getId());
row.addView(btnTag);
}
}
layout.addView(row);`
Try to use TableLayout. Each Row will enforce the entire elements to match the parent with the same wights. You can control number of Buttons into each Row programatically with counter. Loop for end of Counter adding your buttons then add new Table Row
TableLayout tbl=new TableLayout(context);//create table
TableRow tr=new TableRow(context);//create table row
tr.addView(view);//add your button instead of the view
tbl.addView(tr);//add the row into the Table
In the XML file
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/keypad"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:stretchColumns="*">
<TableRow>
<Button android:id="#+id/keypad_1" android:text="#string/_1"></Button>
<Button android:id="#+id/keypad_2" android:text="#string/_2"></Button>
<Button android:id="#+id/keypad_3" android:text="#string/_3"></Button>
</TableRow>
</TableLayout>
I have one little problem...Here is my code..Is there a way to "distribute weights evenly" for those buttons what I made.. I tried to button[i].setWidth().. but when I turn around my phone it looks ugly.. so Is there away to distribute buttons width auto?
ViewGroup row1 = (ViewGroup)findViewById(R.id.TableRow02);
ViewGroup row2 = (ViewGroup)findViewById(R.id.TableRow04);
ViewGroup row3 = (ViewGroup)findViewById(R.id.TableRow06);
ViewGroup row4 = (ViewGroup)findViewById(R.id.TableRow08);
ViewGroup row5 = (ViewGroup)findViewById(R.id.TableRow10);
Button button[] = new Button[36];
for(int i=1;i<36;i++)
{
button[i] = new Button(this);
if(i==32||i==33||i==34||i==35){button[i].setVisibility(-1);}
button[i].setText("700€");
button[i].setTextSize(10);
button[i].setWidth(20);
// Insert buttons in rows
if(i<8){row1.addView(button[i]);}
else if(i<15){row2.addView(button[i]);}
else if(i<22){row3.addView(button[i]);}
else if(i<29){row4.addView(button[i]);}
else if(i<36){row5.addView(button[i]);}
}
Tactically, put the buttons in a LinearLayout and set android:layout_weight="1" for each of them.
Strategically, design a decent UI, one that does not involve a row of 36 buttons.
As CommonsWare said, instead of setting the width, you should consider to set the weight parameter of the buttons in order to achieve a flexible layout.
If you want to achieve this programmatically (i.e. in code and not in the XML layout), you can use the button's setLayoutParams method. I haven't tested it, but something like this should work:
// outside of loop
LayoutParams p = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT,
1.0
);
....
// enter loop
....
button[i].setLayoutParams(p);
In this example, 1.0 represents the weight. The other two parameters represent layout_width and layout_height parameter.
But seriously, I can't imagine that a layout with 36 buttons is very user friendly :-)