How to create a RelativeLayout programmatically with two buttons one on top of the other?
Asked Answered
P

3

71

I'm adding two buttons to the UI, but they appear on top of one another. I want them to appear next to each other. What am I missing in this code?

m_btnCrown = new ImageButton(this);
m_btnCrown.setImageResource(R.drawable.king_crown_thumb);
m_btnCrown.setAlpha(100);

RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);


addContentView(m_btnCrown, lp);


m_btnMonkey = new ImageButton(this);
m_btnMonkey.setImageResource(R.drawable.monkey_small);
m_btnMonkey.setAlpha(100);

lp = new RelativeLayout.LayoutParams(
    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
lp.addRule(RelativeLayout.RIGHT_OF, m_btnCrown.getId());   

addContentView(m_btnMonkey, lp);
Pesce answered 12/2, 2011 at 16:42 Comment(0)
P
22

Found the answer in How to lay out Views in RelativeLayout programmatically?

We should explicitly set id's using setId(). Only then, RIGHT_OF rules make sense.

Another mistake I did is, reusing the layoutparams object between the controls. We should create new object for each control

Pesce answered 13/2, 2011 at 10:37 Comment(1)
The layoutparams part was not wrong. It is totally valid the way you defined it but as you can read in my comment above it was not right how you added the views.Included
I
143

I have written a quick example to demonstrate how to create a layout programmatically.

public class CodeLayout extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Creating a new RelativeLayout
        RelativeLayout relativeLayout = new RelativeLayout(this);

        // Defining the RelativeLayout layout parameters.
        // In this case I want to fill its parent
        RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.FILL_PARENT,
                RelativeLayout.LayoutParams.FILL_PARENT);

        // Creating a new TextView
        TextView tv = new TextView(this);
        tv.setText("Test");

        // Defining the layout parameters of the TextView
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
        lp.addRule(RelativeLayout.CENTER_IN_PARENT);

        // Setting the parameters on the TextView
        tv.setLayoutParams(lp);

        // Adding the TextView to the RelativeLayout as a child
        relativeLayout.addView(tv);

        // Setting the RelativeLayout as our content view
        setContentView(relativeLayout, rlp);
    }
}

In theory everything should be clear as it is commented. If you don't understand something just tell me.

Included answered 12/2, 2011 at 17:9 Comment(5)
Though this sample works, my actual problem (overlapping controls) remains unanswered. More searching revealed the solution in #2305895 We should explicitly set id's using setId(). Only then RIGHT_OF rules make sensePesce
Well that is kind of self-explanatory. If you want to access something by its id you have to set it too. What I wanted to highlight with my answer was that you are doing it wrong. Calling addContentView will override the content view which was set before or which is set with setContentView.Included
I don't think so. Just check this documentation: developer.android.com/reference/android/app/…, android.view.ViewGroup.LayoutParams) which says "Add an additional content view to the screen. Added after any existing ones in the screen -- existing views are NOT removed"Pesce
this answer should be downvoted. It is hardly relevant to the OP's question and goes on a tangentMease
I would recommend if you possibly can, to put the layout in XML and then use LayoutInflater.inflate(...) to create the actual objects. For example, if you needed to create a variable number of buttons, you could have a layout XML representing a single button, then inflate it multiple times in a loop. I have experienced many issues with trying to do everything programmatically, as some properties don't work in the same way as they do in XMLWageworker
P
22

Found the answer in How to lay out Views in RelativeLayout programmatically?

We should explicitly set id's using setId(). Only then, RIGHT_OF rules make sense.

Another mistake I did is, reusing the layoutparams object between the controls. We should create new object for each control

Pesce answered 13/2, 2011 at 10:37 Comment(1)
The layoutparams part was not wrong. It is totally valid the way you defined it but as you can read in my comment above it was not right how you added the views.Included
B
0
public class AndroidWalkthroughApp1 extends Activity implements View.OnClickListener {

    final int TOP_ID = 3;
    final int BOTTOM_ID = 4;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // create two layouts to hold buttons
        RelativeLayout top = new RelativeLayout(this);
        top.setId(TOP_ID);
        RelativeLayout bottom = new RelativeLayout(this);
        bottom.setId(BOTTOM_ID);

        // create buttons in a loop
        for (int i = 0; i < 2; i++) {
            Button button = new Button(this);
            button.setText("Button " + i);
            // R.id won't be generated for us, so we need to create one
            button.setId(i);

            // add our event handler (less memory than an anonymous inner class)
            button.setOnClickListener(this);

            // add generated button to view
            if (i == 0) {
                top.addView(button);
            }
            else {
                bottom.addView(button);
            }
        }

        RelativeLayout root = (RelativeLayout) findViewById(R.id.root_layout);

        // add generated layouts to root layout view
       // LinearLayout root = (LinearLayout)this.findViewById(R.id.root_layout);

        root.addView(top);
        root.addView(bottom);
    }

    @Override
    public void onClick(View v) {
        // show a message with the button's ID
        Toast toast = Toast.makeText(AndroidWalkthroughApp1.this, "You clicked button " + v.getId(), Toast.LENGTH_LONG);
        toast.show();

        // get the parent layout and remove the clicked button
        RelativeLayout parentLayout = (RelativeLayout)v.getParent();
        parentLayout.removeView(v);



    }
}
Baggott answered 17/5, 2015 at 8:31 Comment(1)
The buttons are on top of each other for your code too.Communicative

© 2022 - 2024 — McMap. All rights reserved.