android adding views dynamically - android

I am adding views dynamically in a linear layout as follows:
xml:
<LinearLayout
android:id="#+id/part1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:gravity="right"
android:orientation="horizontal" >
</LinearLayout>
java:
View linearLayout = findViewById(R.id.part1);
((LinearLayout) linearLayout).removeAllViews();
for (int i = 0; i < 15; i ++){
TextView tv = new TextView(this);
tv.setText(String.valueOf(i));
LinearLayout.LayoutParams lay = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(lay);
tv.setBackgroundResource(R.drawable.msg);
tv.setId(i);
((LinearLayout) linearLayout).addView(tv);
}
Now i have two questions:
1) the text views are added horizontally correctly but if not fitting screensize, some of them won't appear, how to force it to continue adding in a new line once the horizontal space is full ?
2) textviews are added from left to right, how to add them from right to left ?
thanks

You need to understand how ViewGroups work, in this case, LinearLayout will add items horizontally or vertically without making position calculations for you unless you explicitly specify (jumping to next line is not one of them...), think of it as an item holder that will show items only on the space you specify for it (thats why some of the elements disappear...), by default the way LinearLayout arrange items is from left to right or up to down, if this do not fit your needs, you could go for any of the ViewGroup options android has, the most important might be:
RelativeLayout
FrameLayout
TableLayout
AbsoluteLayout(not recommended)
If you need some sort of Free Draw on the screen, you can always go for a View object, override onDraw, and play with the canvas of that object...
Regards!

Related

Android add multiple Textviews programmatically to Layout line break

I need to add TextViews to a Layout (RelativeLayout or LinearLayout I don't care) programatically.
I want something like this:
After the textview 4 there is no more space on the right side so the next TextView will be placed in a new Line bellow.
This is what I have done:
Create a LinearLayout in the xml file:
<LinearLayout
android:id="#+id/my_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
In my code, I loop over a list of Objects and add a new TextView for each objekt:
LinearLayout myLinearLayout = (LinearLayout) itemView.findViewById(R.id.my_linear_layout);
for(MyObject object : myObjectList) {
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(20, 0, 20, 0); // llp.setMargins(left, top, right, bottom);
final TextView textView = new TextView(context);
textView.setText(object.getName());
textView.setLayoutParams(params);
myLinearLayout.addView(textView, params);
}
But this is the result I get:
I have thought adding LinearLayouts vertically instead of TextViews, but still my problem is that I don't know when I need to add the next the next one, I mean, when there is no more space on the right side.
I have also tried it with TableLayout but still the same problem, I don't know when I have to add the next row.
Any ideas? Maybe there is a View that already solves that problem and I don't know...

Create buttons side by side dynamically

I have the following method which I call a few times to create a list of buttons. It works well and creates the buttons.
public void CreateButton(int i) {
LinearLayout btnLayout = (LinearLayout)findViewById(R.id.btnLayout);
Button btn = new Button(this);
btn.setId(i);
btn.setText(String.valueOf(i+1));
btnLayout.addView(btn);
}
But each created button is fitting the screen in width, and I would want it to stay side by side, two buttons per row. I managed to set the button to half the screen size using this:
int displaywidth= getResources().getDisplayMetrics().widthPixels;
btn.setLayoutParams(new LayoutParams((int)(displaywidth/2), LayoutParams.WRAP_CONTENT));
It makes the button's width to be half the screen's size, but I can't figure out how to place them side by side. Any help is appreciated.
Change your orientation in your LinearLayout to horizontal.
<LinearLayout
...
android:orientation="horizontal"
... >
...
</LinearLayout>
If you only have a single LinearLayout that is to hold multiple side-by-side buttons you can make horizontal LinearLayouts to hold your button pairs and either nest them in the main veritical layout or utilize another layout, for example RelativeLayout, to get the desired results.
Try using weight property of LinearLayout. If in each row you want only two buttons then give
android:weightSum="1"
to LinearLayout and
android:layout_weight="0.5"
to each button or you can set weight dynamically in your code by
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, xf);
where x represents the float value of layout weight of your button.
for more details about layout weight http://developer.android.com/guide/topics/ui/layout/linear.html
One way to solve the problem is by using their weight and width. Make sure the Linear Layout has a horizontal orientation. Then, use Layout_params to set their width to "Wrap_Content" and their weight to "1". Then both will automatically take up the same amount of space.

Dynamic overlapping tab host

So I have tried horizontal listview (adapter), but I cannot get the padding in the left so it will overlap each other. it's just separated like in wrap content. any suggestion on how to do this dynamically?
http://www.bild.me/bild.php?file=8656221tabs.jpg
I even tried dynamic addview
<LinearLayout
android:id="#+id/frag_productline_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
for (int i = 0 ; i < productList.size(); i++){
TextView tv = new TextView(context);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT) );
tv.setPadding(-40, 0, 0, 0);
tv.setText(productList.get(i));
tv.setBackgroundResource(R.drawable.tab);
layout.addView(tv);
}
But it looks like just an adapter I've tried in horizontal list view . Even worse with no handling of onItemClickListener
I suggest having an absolute layout/relative layout and scroll view instead of horizontal list view. Programmatically append the image buttons in an overlapped manner.
You can't overlap views by setting a negative padding. However, you can give them a negative margin.
LayoutParams lp = tv.getLayoutParams();
lp.setMargin(negative left margin, top, right, bottom);
tv.setLayoutParams(lp);

Adding Textviews Dynamically goes out of focus to a Linear Layout

I am trying to achieve a dynamic list of textviews like in the image below :-
Here is my code :-
LayerDrawable dashboardResShape_community= (LayerDrawable) getResources().getDrawable(R.drawable.upcomingtask_tags_shape);
// The background effect is by the layer list drawable from the above code
LinearLayout tags_view2=(LinearLayout)findViewById(R.id.tags_view);
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 2, 2, 2);
TextView[] tx = new TextView[15];
for(int i=0; i<15; i++) {
tx[i] = new TextView(getActivity());
tx[i].setPadding(8, 4, 8, 4);
tx[i].setBackground(dashboardResShape_community);
tx[i].setLayoutParams(lp);
tx[i].setText("Tag"+i);
tags_view2.addView(tx[i]);
}
and in my xml there is only a linear layout :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tags_view"
android:orientation="horizontal" >
</LinearLayout>
This is what i achieve :-
When i am adding 15 textviews, only 8 are shown like below, the rest should come in the next line but they are not.
If i add more textviews, it goes out of screen but i want to add the textview in the second line when the first line is full. What i am doing wrong here?
Its LinearLayout's limitation.
If you want the explained behavior than
You have to make your own Layout/View refer this link or
Impliment LinearLayout Horizontal orientation with wrapping children like this
you cannot get more text views on next line after linear layout is filled( screen width ), you already the made linear layout orientation as horizontal. Better solution add one more linear layout or use relative (do some child count coding and set parameters). The best solution i prefer for u is table layout. Easier to code code and handle
What you can do is add as many textviews as will fit on the screen to your linearlayout, but then when a textview would go off the screen, you could add another linearlayout below the one that you already had, and then add on to that. You could keep doing that and you would end up with no textviews goind off the screen. You could also try using a gridview.
Here is what this layout looks like:
http://developer.android.com/guide/topics/ui/layout/gridview.html
And here is the documentation:
http://developer.android.com/reference/android/widget/GridView.html

RelativeLayout add rule "RelativeLayout.LEFT_OF" not working

I have a relativeLayout like below:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:id="#+id/parent" >
<ListView
android:layout_width="360dp"
android:layout_height="600dp"
android:id="#+id/list"
android:inputType="text"
android:maxLines="1"
android:layout_margin="50dp"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
In the java code, I want to add a view to the left of the listview, but it didn't worked:
m_relativeLayout = (RelativeLayout)findViewById(R.id.parent);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.LEFT_OF, m_listView.getId());
Button button2 = new Button(this);
button2.setText("I am button 2");
m_relativeLayout.addView(button2, layoutParams);
only if I set the listview to alignParentRight, it will work. Is this an android bug or I'm missing something?
I always try addView(View child, int index, LayoutParams params), but it might only work in the linearlayout. So is there an normal solution to make the RelativeLayout.LEFT_OF work?
EDIT
I have tried RelativeLayout.BELOW and RelativeLayout.RIGHT_OF, and they worked perfectly, so it means I don't have enough place to get the button? I tried to give more space, but it still not work.
I use Toshiba AT100 (1280*800) and landscape, so the space is enough. Test below and right just same as the left. I think If i put an control A in the relativelayout, then I add control B and decalare it's on the left of the control A, the result should be the control B will push the control A to its right, right?
I think If i put an control A in the relativelayout, then i add control B and declare it's on the left of the control A, the result should be the control B will push the control A to its right, right?
Your assumption is incorrect, the control A will not be pushed to the right unless you specified this with a RelativeLayout.LayoutParams rule. RelativeLayout places its children one one top of each other starting at the top-left corner of the screen if you don't specify placement rules for them. When you add the View A to the RelativeLayout without any rules(like layout_alignParentRight) it will be placed starting from the top-left corner of the screen. Then, when you add the View B, the rule to_leftOf will apply to this View position but this rule doesn't mean anything for the View A who will maintain its position on the screen. This will make View B to be place to the left of View A but outside of the screen as View A bounds start from the left border of the screen.
The Button will be placed to the left of the ListView when you use layout_alignParentRight="true" because there is now space to actually see the Button(it's not outside anymore). addView(View child, int index, LayoutParams params) works in a LinearLayout because the LinearLayout arranges its children in a row or column(depending on orientation) so when you add a View at a specific position, it will push the other Views after it to the right or below(depending on orientation)(there is no relative positioning of the views in a LinearLayout, the only rule is that the children come one after the other).
Starting with the ListView without any rules set on it, here is an example on how to make the Button to appear on the left of the ListView:
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
Button button2 = new Button(this);
button2.setText("I am button 2");
button2.setId(1000);
m_relativeLayout.addView(button2, layoutParams);
RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) m_listView
.getLayoutParams();
rlp.addRule(RelativeLayout.RIGHT_OF, button2.getId());
The Button will be added as normal to the screen and it will appear starting from the top-left corner of the screen. Without the two lines from the code above the Button and ListView will overlap as this is the normal behavior of RelativeLayout for children without any rules on them. We then explicitly modify the position of the ListView to move it to the right(with the last two line from the code above).
If your variable names are indicative, it's because you are adding the widget to a LinearLayout, so tags for a RelativeLayout get ignored.
This line is the one I'm talking about:
m_linearLayout.addView(button2, layoutParams);
EDIT
You say alignParentRight works... the only difference there is that ot doesn't take an anchor parameter. Perhaps m_listView.getId() isn't returning the proper id. You could step through with the debugger and see if it's returning a proper value.
Maybe you could try calling the id specifically...
layoutParams.addRule(RelativeLayout.LEFT_OF, R.id.list);
To perform it, use predefined view ID or declare one. In values folder create ids.xml then add a Item like this:
<item name="imageViewID" type="id"/>
use this id in your code where you are creating new Instance of view like this:
RelativeLayout layout=new RelativeLayout(context);
ImageView imageView = new ImageView(context);
imageView.setId(R.id.imageViewID);
RelativeLayout.LayoutParams layoutParams = new LayoutParams(50, 50);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
layout.addView(imageView, layoutParams);
TextView textView = new TextView(context);
RelativeLayout.LayoutParams textViewParams= new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
textViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
textViewParams.addRule(RelativeLayout.BELOW, imageView.getId());
layout.addView(nameView, nameLayoutParams);
or we can directly use this function View.generateViewId() to perform the same. Like this:
imageView.setId(View.generateViewId());
I think you might have forgotten to add m_listView to the RelativeLayout or m_listView's visibility would be GONE.
Can you please check for that?
setId before align is called, especially for the new object view.
If you are using a custom id and not a regular generated Android id (eg. R.id.my_id), make sure that the id is not equal to 0 (or negative), otherwise the rule will be ignored.

Categories

Resources