Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 208
dreamtale Avatar asked May 22 '12 10:05

dreamtale


People also ask

Is RelativeLayout deprecated?

relativelayout is deprecated now.

Which is better LinearLayout or RelativeLayout?

Relativelayout is more effective than Linearlayout. It is a common misconception that using the basic layout structures leads to the most efficient layouts. However, each widget and layout you add to your application requires initialization, layout, and drawing.

How do I set TextView in center in RelativeLayout?

android:gravity controls the appearance within the TextView. So if you had two lines of text they would be centered within the bounds of the TextView. Try android:layout_centerHorizontal="true" . Notice that this won't work if a RelativeLayout contains an attribute android:gravity="center_horizontal".


2 Answers

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

like image 175
user Avatar answered Dec 27 '22 03:12

user


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);
like image 32
Barak Avatar answered Dec 27 '22 03:12

Barak