MidnightJava
MidnightJava

Reputation: 1997

Android: Add views programmatically and layout is not obeyed

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));

Upvotes: 0

Views: 848

Answers (2)

Rhys Davis
Rhys Davis

Reputation: 996

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

Upvotes: 1

MidnightJava
MidnightJava

Reputation: 1997

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);

Upvotes: 0

Related Questions