Using a nested LinearLayout - android

SOLVED: The layout_height parameter was set to Match_parent in the buttonbar definition. Changed to wrap_content.
I'm currently working on a new App which has a series of buttons at the top of the main screen. the "buttonBar" XML defines a linearLayout and is later nested within another linearLayout.
The buttons appear fine and work however if I then put a text view beneath the include statement the text does not appear. I think that it is actually appearing behind the buttons. I assumed that because it was within a parent linearLayout that it would appear after the included (nested) nested layout.
please could someone explain why this is not occurring and point me in the right direction to solve it.
much appreciated,
M
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<include layout="#layout/buttonheader"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:id="#+id/textView1"
android:textColor="#ffffff">
</TextView>
</LinearLayout>

Set height and width of the included layout buttonheader
SO that you can see this included layout in your layout

Related

layout_gravity="center_vertical" not working

My problem
I can't seem to figure out why android:layout_gravity="center_vertical" is not working in my case.
Please note that I am not interested in solving the problem of making it vertically aligned, so much so that I am trying to understanding exactly what is the cause of this behavior itself for pedagogical reasons.
My code
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/blue_100">
<android.support.v7.widget.AppCompatTextView
android:background="#color/red_100"
android:text="HELLO WORLD"
android:textSize="18sp"
android:textColor="#color/black"
android:gravity="center_vertical"
android:maxLines="2"
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v7.widget.LinearLayoutCompat>
A LinearLayout with vertical orientation will ignore the vertical component of any child's android:layout_gravity attribute. Similarly, a LinearLayout with horizontal orientation will ignore the horizontal component of a child's android:layout_gravity.
For the special case of the center gravity value, it's helpful to know that this behaves identically to center_horizontal|center_vertical, down to the actual integer value of the constants (0x11 vs 0x01|0x10). As such, using android:layout_gravity="center" in a vertical linear layout will be equivalent to just android:layout_gravity="center_horizontal".
As for why, consider this:
<LinearLayout orientation=vertical>
<View layout_gravity=top/>
<View layout_gravity=bottom/>
</LinearLayout>
What would you do here? If you position the first view at the top of the screen and the second view at the bottom of the screen, then you're not really a linear layout.
Even though you said you're not interested in how to solve the problem, you can do so with the android:gravity attribute on the LinearLayout itself. This will cause the LinearLayout to stack all the views together at the top, center, or bottom of the linearlayout.

scrollview warning

i made a simple test for an android app to ScrollView a TextView, almost there are no errors but i get a Warning ( This ScrollView layout or its LinearLayout parent is useless) and i dont know what to do . i wish i get your help
here is the code:
<LinearLayout android:id="#+id/LinearLayout01"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<ScrollView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1">
<TextView android:id="#+id/TextView01" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hi"/>
</ScrollView>
</LinearLayout>
Take a second to think about it! If the linear layout takes up all the space it could take up (say 200x400 pixels), then the Scroll view takes up as much space as the linear layout can take up (200x400 pixels), then your linear layout has just become useless! (in theory)
Try to add more stuff after you scroll view -- this may make your warning go away
should be the top most parent... Remove your LinearLayout from top ant you are done.

Android - fill_parent not behaving as expected in RelativeLayout

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background_gradient" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" >
<ImageButton
android:id="#+id/buttonLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/log"
android:onClick="log" />
</RelativeLayout>
</FrameLayout>
I was expecting my button to appear in the center of the screen. However, it appears on the TOP center of the screen (that is, the button is center horizontally, but not vertically).
It seems to me that the RelativeLayout is behaving like it was defined with "wrap_content" instead of "fill_parent".
The funny thing is that, if I give an actual value to my RelativeLayout height property (android:layout_height), like:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="100dp"
android:gravity="center" >
Then the button behaves correctly (i.e. the button is also centred vertically). But I don`t want to use actual values. I want to use fill_parent! Why doesn't it work with "fill_parent" ??
Does anybody know what's going on?
Thank you in advance!
RelativeLayout requires you to specify the position of the elements in the Layout. I don't see any layout_below or layout_toLeftOf tags. Gravity works on LinearLayouts. In general, LinearLayouts are easier to work with, and they scale much better to different screen sizes. I suggest you replace the RelativeLayout by a LinearLayout, and also the FrameLayout by a LinearLayout. You use a FrameLayout typically if you want to use multiple overlapping layouts, which you don't do.
I recommend you read up on using layouts in the Android sdk reference documentation, like here: http://bit.ly/djmnn7
You specified fill_parent for both the layout_width and layout_height of your RelativeLayout, therefore it fills up it's parent view.
By default, a relative layout arranges it's children to the top-left corner, regardless you use fill_parent for the size.
You should achieve the desired aspect by taking advantage of the RelativeLayout's own attribute set, which helps you arrange the child views relatively to each other or to their parent:
<ImageButton
android:id="#+id/buttonLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#drawable/log"
android:onClick="log" />
Using the android:layout_centerInParent you can achieve this. This attribute if set true, centers this child horizontally and vertically within its parent.

Reserve a "slot" in a layout XML file for a dynamically created button?

In my app, I have one (and only one) UI element which isn't referenced in the XML layout file.
That element is a button, instantiated and returned at run-time by a 3rd party library (i.e. I don't have control over that).
My problem is that I would like some of the elements (TextViews) in the XML layout file to be placed relative to that button, using RelativeLayout.
Is it possible to "reserve an empty slot" in the XML layout file for that button such that I can do something like the following?
<TextView android:id="#+id/tv_text_under_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/btn_dynamically_created_button"
android:text="" />
Alternatively, if I were to set the layout at run-time using RelativeLayout.LayoutParams.addRule(), what would be the ID of that dynamically created button, if it has no reference at all in the XML layout file?
For example, in the following call:
layoutParams.addRule(RelativeLayout.BELOW, R.id.btn_dynamically_created_button);
What would I put instead of R.id.btn_dynamically_created_button?
Update: Thanks to the answer below, I created a place holder like this:
<LinearLayout android:id="#+id/btn_dynamically_created_button"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</LinearLayout>
The challenge now is: How to associate the returned object from getDynamicallyCreatedButton() (returned object is subclass of LinearLayout, not Button), with R.id.btn_dynamically_created_button?
EDIT: This thread seem to address a similar issue, but I am not sure that I understand the solution offered.
I'd suggest:
Put a LinearLayout with width/height set to wrap-content, horizontal orientation and zero padding as the placeholder.
Orient all the other things to that LinearLayout.
When its time to put the button, simply stick it into the LinearLayout.
See if that works for you.
EDIT: attempt at a short example:
The layout (suitably shortened): you can place other components relative to the LinearLayout with id LinearLayout01.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_marginTop="2sp" android:layout_marginBottom="2sp" android:layout_height="wrap_content">
<LinearLayout android:id="#+id/LinearLayout01" android:layout_height="wrap_content" android:layout_width="wrap_content" android:gravity="right" style="#style/SimpleButtonBar" android:layout_below="#+id/rootlayout" android:layout_alignParentBottom="true">
</LinearLayout>
<ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentTop="true" android:layout_above="#+id/LinearLayout01" android:fillViewport="true">
<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="#+id/detaillayout">
</RelativeLayout>
</ScrollView>
</RelativeLayout>
The code (for example, this would go in onCreate): fetch your button (you need to make sure it has the right Context, but I figure you're doing that alright), fetch the LinearLayout, create a layout parameters object and stick your button into the LinearLayout.
Button b = getButton(); // retrieve your button somehow
LinearLayout l = (LinearLayout)findViewById(R.id.LinearLayout01);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
l.addView(b, lp);

LinearLayout, RelativeLayout, etc. margins do not work as expected

Margins in group layouts do not seem to work.
For example,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_margin="40dip"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I'm a button" />
</LinearLayout>
should display a button with 40p margins on all sides. However, it has 80p margins on the right and bottom.
Am I doing something wrong?
Is this a bug?
A workaround would be to use gravity, but this only works with even margins.
BTW, there is a similar question posted here but has not been answered.
android:padding="40dp" on the LinearLayout or android:layout_margin="40dp" on the Button will give you the effect you want. Padding defines the space between a views edges and its content, layout margin defines extra space on the sides of a view.
The problem is actually the way FrameLayout interprets margins. setContentView() attaches your "main" layout to a FrameLayout, which is the actual root of the view hierarchy (you can see that with Hierarchy Viewer) and is offered to you by the phone.
Margins are managed by the parent layout, so in this case that main FrameLayout. I don't know if it's a feature or a bug, but that's how this layout interprets margins.
So well, the solution was already posted while I was typing: use padding instead.
if you need set margin for a layout, simply wrap it with another linear or relative layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:layout_margin="40dip"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="I'm a button" />
</LinearLayout>
</LinearLayout>
Wrapping the Linear Layout with another layout is the best strategy.

Categories

Resources