Android: Add views programmatically and layout is not obeyed - android

I have an onClickListener in which I try to add two views dynamically to an existing ViewGroup. I simply want to add one to the right of the other, but no matter what I do, they're rendered right on top of each other, with their left edges aligned. Other aspects of the layout are obeyed. For example I can specify a width as MATCH_PARENT and the View is rendered as such. Also, I'm mimicking programmatically how I specified a layout for a different ViewGroup in XML, and the XML-specified layout works properly. Here is my code:
Editable nodeName = nodeSelectView.getText();
View insertPoint = findViewById(R.id.insertionPoint);
//the two views to be added dynamically
EditText nodeView = new EditText(ManageDomainsActivity.this);
Button nodeButton = new Button(ManageDomainsActivity.this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
lp.addRule(RelativeLayout.LEFT_OF, nodeButton.getId());
nodeView.setLayoutParams(lp);
nodeView.setGravity(Gravity.LEFT);
nodeView.setText(nodeName.toString());
lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
lp.addRule(RelativeLayout.RIGHT_OF, nodeView.getId());
lp.addRule(RelativeLayout.ALIGN_BASELINE, nodeView.getId());
lp.addRule(RelativeLayout.ALIGN_BOTTOM, nodeView.getId());
nodeButton.setLayoutParams(lp);
nodeButton.setText("Kill");
nodeButton.setGravity(Gravity.CENTER);
((ViewGroup) insertPoint).addView(nodeView, 0,
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
((ViewGroup) insertPoint).addView(nodeButton, 1,
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));

You need to set the ID's of the views you're creating programatically since using getId() on a view without an id returns a NO_ID constant which doesn't work in RelativeLayout rules. Programatically created views do not need globally unique IDs (only unique in the viewgroup) so you can just set them as 1, 2, 3, ... etc

The problem was that the LayoutParameters I was passing in addView() were overriding the ones I had set on the respective views. It also failed because of a circular dependency, since the two views were defined to the right and left of each other, respectively. This doesn't seem circular to me, and it works fine in the XML that way, but it threw an exception in the dynamic layout assignment. Here's the code that works:
Editable nodeName = nodeSelectView.getText();
View insertPoint = findViewById(R.id.insertionPoint);
EditText nodeView = new EditText(ManageDomainsActivity.this);
nodeView.setId(1);
Button nodeButton = new Button(ManageDomainsActivity.this);
nodeButton.setId(2);
RelativeLayout.LayoutParams lpView = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lpView.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
nodeView.setLayoutParams(lpView);
nodeView.setGravity(Gravity.LEFT);
nodeView.setText(nodeName.toString());
RelativeLayout.LayoutParams lpButton = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lpButton.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
lpButton.addRule(RelativeLayout.RIGHT_OF, nodeView.getId());
lpButton.addRule(RelativeLayout.ALIGN_BASELINE, nodeView.getId());
lpButton.addRule(RelativeLayout.ALIGN_BOTTOM, nodeView.getId());
nodeButton.setLayoutParams(lpButton);
nodeButton.setText("Kill");
nodeButton.setGravity(Gravity.CENTER);
((ViewGroup) insertPoint).addView(nodeView, lpView);
((ViewGroup) insertPoint).addView(nodeButton, lpButton);

Related

Add an ImageButton programmatically with a Chosen Size

I'm on Android Studio, and I would like to create an ImageButton in my code. The problem is, when I create it, I don't know how to set its size (It's too big).
I proceed like this: I have a linear layout created with xml (added) where i put I put a RelativeLayout which contains a TextView and my ImageButton. I set the params when I put my IB in the layout. Here is the code:
final RelativeLayout rl = new RelativeLayout(Selection.this);
final TextView someone = new TextView(Selection.this);
final ImageButton cross = new ImageButton(Selection.this);
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
cross.setBackgroundResource(R.drawable.stop);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
cross.setLayoutParams(lp);
cross.setScaleType(ImageView.ScaleType.FIT_XY);
someone.setText(et.getText());
rl.addView(someone);
rl.addView(cross);
added.addView(rl,rlp);
The parameters the ImageButton gets are those of lp which you set with width and height RelativeLayout.LayoutParams.WRAP_CONTENT , therefore the ImageButton will use the size of the image which might be too big for you. Try choosing a specific size :
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
60,60);
or add the ImageButton view inside another layout that you already constrained its sizes.

RelativeLayout.BELOW doesn't work in programmatically created RelativeLayout

I'm creating a Layout programmatically consisting of a RelativeLayout and some TextViews. I want them to be placed like two columns like following example:
textview0 textview1
textview2 textview3
textview4 textview5
and the following LayoutParameters is applied to them:
width: WRAP_CONTENT
height: WRAP_CONTENT
and rules for example textview4:
RelativeLayout.BELOW, textview3.getId()
RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE
and rules for textview5:
RelativeLayout.RIGHT_OF, textview4.getId()
RelativeLayout.ALIGN_BASELINE, textview4.getId()
This ensures that the contents in column to the right can be wrapped but textviews below it is still showing fine, as it's placed below the textview that could be wrapped.
Well, when I try this out I get it to work for the first two rows of textviews, they are placed as they should, but then I add a third one and that one get placed on the same row as it should be placed below. And I cant figure out what's wrong.
RelativeLayout rl = new RelativeLayout(context);
rl.setPadding(5, 5, 5, 5);
rl.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
RelativeLayout.LayoutParams lp0 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp0.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
textView0.setLayoutParams(lp0);
rl.addView(textView0);
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp1.addRule(RelativeLayout.RIGHT_OF, textView0.getId());
lp1.addRule(RelativeLayout.ALIGN_BASELINE, textView0.getId());
lp1.setMargins(5, 0, 0, 0);
textView1.setLayoutParams(lp1);
rl.addView(textView1);
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp2.addRule(RelativeLayout.BELOW, textView1.getId());
lp2.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
textView2.setLayoutParams(lp2);
rl.addView(textView2);
RelativeLayout.LayoutParams lp3 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp3.addRule(RelativeLayout.RIGHT_OF, textView2.getId());
lp3.addRule(RelativeLayout.ALIGN_BASELINE, textView2.getId());
lp3.setMargins(5, 0, 0, 0);
textView3.setLayoutParams(lp3);
rl.addView(textView3);
RelativeLayout.LayoutParams lp4 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp4.addRule(RelativeLayout.BELOW, textView3.getId());
lp4.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
textView4.setLayoutParams(lp4);
rl.addView(textView4);
RelativeLayout.LayoutParams lp5 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp5.addRule(RelativeLayout.RIGHT_OF, textView4.getId());
lp5.addRule(RelativeLayout.ALIGN_BASELINE, textView4.getId());
lp5.setMargins(5, 0, 0, 0);
textView5.setLayoutParams(lp5);
rl.addView(textView5);
So the example code above results in textView4 being placed above textView2 even though it should be placed below it, ruled by LayoutParameters for textView3. I can't see anything wrong with this code, and I have debugged it to ensure that the ID's was unique among the textviews and they are.
Any suggestions, I'm kind of stuck!

android dynamically add layouts under each other

I'm trying to add multiple layouts dynamically under each other. So I wrote the following code:
for (int i = 1; i <= layoutCounter; i++) {
View neu = inflater.inflate(R.layout.vote, parent, false);
neu.setId(layoutID);
if (layoutID == 1) {
params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, R.id.txtMultiline);
} else {
params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, neu.getId());
}
neu.setLayoutParams(params);
parent.addView(neu);
layoutID++;
}
txtMultiline is a fixed View defined in XML. LayoutID is an integer and starts with 1. The first layout is added correctly under the txtMultiline TextView. But all following layouts just get added on top of the parent layout (which is a RelativeLayout). Can't get the reason.. else-route is executed correctly. But the BELOW constant seems to have no effect when trying to apply it to my dynamically inflated layouts. What am I doing wrong?
Maybe with:
params.addRule(RelativeLayout.BELOW, layoutID-1);
instead of:
params.addRule(RelativeLayout.BELOW, neu.getId());
in your else condition.
You can try like this
RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(...)
rl.addRule(RelativeLayout.BELOW, anotherview.getId())
rl.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
parentLayout.addView(myView, rl)

Programmatically aligning items in RelativeLayout?

I'm trying to position items inside my RelativeLayout so that the image appears first, the title to the right of it, and the content below the image area. Those three content items appear on top of each other. I understand that my LayoutParams probably aren't being set, but I'm not sure why or how to fix it. Any help? Thanks.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.contentTable);
for(int i=0;i<itemIndexes.size();i++)
{
RelativeLayout item = new RelativeLayout(this);
item.setId(i);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(320, RelativeLayout.LayoutParams.WRAP_CONTENT);
if(i>0)
{
lp.addRule(RelativeLayout.RIGHT_OF,i-1);
}
item.setLayoutParams(lp);
ImageView iv = new ImageView(this);
if(globals.myHitetItems.get(itemIndexes.get(i)).image!=-1)
{
iv.setImageResource(globals.myHitetItems.get(itemIndexes.get(i)).image);
item.addView(iv);
}
else
{
iv.setImageResource(R.drawable.noimage);
item.addView(iv);
}
RelativeLayout.LayoutParams text1lp =new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
text1lp.addRule(RelativeLayout.RIGHT_OF,iv.getId());
TextView tv = new TextView(this);
tv.setText(globals.myHitetItems.get(itemIndexes.get(i)).name);
tv.setTextSize(20);
tv.setPadding(3, 3, 3, 3);
tv.setLayoutParams(text1lp);
item.addView(tv);
RelativeLayout.LayoutParams text2lp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
text2lp.addRule(RelativeLayout.BELOW,iv.getId());
tv = new TextView(this);
tv.setText(globals.myHitetItems.get(itemIndexes.get(i)).content);
tv.setTextSize(20);
tv.setPadding(3, 3, 3, 3);
tv.setLayoutParams(lp);
item.addView(tv);
rl.addView(item);
}
That looks painful to debug. It sounds like maybe the relative rules aren't being set or accepted. I suggest simplifying to a static test set to verify that one row of views can be set relative to each other (and ensure that one of them is anchored to the layout itself).

text is not coming at the bottom of the screen

HI , why my text is not coming at the bottom evethough i have given tParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
Here is my code please help,
footScroll_relative = new RelativeLayout(this);
footScroll_scrollView = new ScrollView(this);
footScroll_horizontalScrollView = new HorizontalScrollView(this);
test_text = new TextView(this);
footScroll_relative.setLayoutParams(new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,android.view.ViewGroup.LayoutParams.FILL_PARENT));
LayoutParams tParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
tParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
footScroll_horizontalScrollView.setLayoutParams(new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,android.view.ViewGroup.LayoutParams.FILL_PARENT));
footScroll_scrollView.setLayoutParams(tParams);
test_text.setText("Ramesh ");
footScroll_horizontalScrollView.addView(test_text);
footScroll_scrollView.addView(footScroll_horizontalScrollView);
footScroll_relative.addView(footScroll_scrollView);
setContentView(footScroll_relative);
this is an example of how to
TextView tView = ((TextView)view.findViewById(R.id.seekBarFilterLabel));
LayoutParams tParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
tParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
tView.setLayoutParams(tParams);
Hope this helps
EDIT: well, in your previuos unedited question you ask how to align the text at a RelativaLayout parent bottom, but here you are adding the TextView inside a HorizontalScrollView, wich is incorrect, the rule RelativeLayout.ALIGN_PARENT_BOTTOM are only valid if you are adding a view inside a RelativeLayout, not inside of ScrollView.

Categories

Resources