What I'm trying to do is have a TextView, and to the right of it an editText that takes up the rest of the space. The textView should be centered vertically along the editText. Now I can do this using an linearlayout, however I would prefer to do it in a relativelayout.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:id="#+id/loginText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Login:"
android:paddingRight="20dp" />
<EditText
android:id="#+id/login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/loginText" />
</RelativeLayout>
What you want to do is possible by using the android:layout_alignBottom and android:layout_alignTop properties provided by the RelativeLayout to its children and the android:gravity property of the TextView.
These properties allow you to set the bottom/top edge of a view to match the bottom/top edge of another view. By applying them to the TextView you can effectively make the TextView match the height of the EditText control. Then, with the gravity property you can make the text in the TextView center vertically inside the TextView control.
The following example should work as you intended:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp" >
<TextView android:id="#+id/user_name_label"
android:text="#string/user_name"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_alignBottom="#+id/user_name_text"
android:layout_alignTop="#id/user_name_text"
android:layout_marginRight="5dp"
android:gravity="center_vertical" />
<EditText android:id="#id/user_name_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#id/user_name_label" />
</RelativeLayout>
add android:layout_gravity="center_vertical" to your Textview
this would place the textview centered vertically in the parent
Related
I have a simple LinearLayout and I try to make it looks like this:
Instead it looks like:
My xml is:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="miasto"
android:textSize="10sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="ulica"
android:textSize="15sp"
android:gravity="bottom"
/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="30sp"
android:text="22"
android:gravity="bottom"/>
</LinearLayout>
Why gravity="bottom" doesn't work?
You set this text view a width of wrap_content it means, what ever the text is, the view take the size of the text and for LinearLayout , the default gravity is center
Thus, Change
android:layout_height="wrap_content"
to
android:layout_height="match_parent"
Meanwhile, just for your information, gravity is the way the text will align itself in the TextView. The TextView being in wrap_content does nothing, as the TextView is exactly the size of the text.
layout_gravity is the way the TextView will align itself in its parent, in your case in the LinearLayout.
Try to make your textview height match_parent.
I have a simple TextView inside of a RelativeLayout.
I want to position end edge of TextView to center of the RelativeLayout as in image below
I found something like android:layout_toStartOf=...
Example:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf=...
/>
</RelativeLayout>
But this only aligns the end edge to start of something. (Can't be used for align end edge to CENTER of layout).
NOTE: There is already a similar question and answer here.
You need to have a widget in the RelativeLayout that you can use as a reference to position the TextView. An empty Space widget (0dp x 0dp) centered horizontally works well for this.
<RelativeLayout>
<!-- Empty space widget (0x0 dp) centered horizontally -->
<Space
android:id="#+id/spacer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerHorizontal="true"
android:visibility="invisible"/>
<!-- TextView to left of the spacer-->
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/spacer"
android:text="awesome text!"/>
</RelativeLayout>
You could create a dummy View centered within your RelativeLayout and then align the TextView left to it:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/center_anchor"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerHorizontal="true" />
<TextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/center_anchor"
android:text="hello world" />
</RelativeLayout>
You may also have a look at the PercentRelativeLayout which supports percentage based dimensions and margins. That means you can specify a right margin of 50% for example.
You can do that using PercentRelativeLayout
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#android:color/white"
android:text="TextView"
android:textColor="#android:color/black"
app:layout_marginRightPercent="50%" />
I'm new on Android.
How can I align a textView with the center of an ImageView using a relative layout?
I have try the following code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<ImageView
android:id="#+id/item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="15dp"
android:maxWidth="15dp"
android:src="#drawable/icon" />
<TextView
android:id="#+id/item_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/item_icon"
android:text="Counter" />
</RelativeLayout>
but the text is not aligned with the center of the picture.
Thanks!
Use layout_alignTop and layout_alignBottom to align the top and bottom of the textview to the imageview. Then make sure the text has center gravity. This should align it to the middle. ( I believe it should be the right gravity by default, but forcing it never hurts).
You just need to align your textview between the borders of your imageviews top and bottom. And also be sure to center your textview's gravity, so that it will just centered inside your imageview.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<ImageView
android:id="#+id/item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="15dp"
android:maxWidth="15dp"
android:src="#drawable/icon" />
<TextView
android:id="#+id/item_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/item_icon"
android:layout_alignTop="#+id/item_icon"
android:gravity="center"
android:text="Counter" />
For a better approach, IMHO, add your imageview to your textview as a drawableLeft, so that it will represent much more to user.
Relative layout children can use:
android:layout_centerInParent="true"
In my horizontal LinearLayout, I set the gravity in one view to be center_vertical, and then I tried to set layout_gravity for a second view, but that view is lined up with the centered text in the first view!
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:layout_width="100dp"
android:layout_height="200dp"
android:layout_gravity="top"
android:background="#drawable/border"
android:gravity="center_vertical"
android:text="layout_gravity=top gravity=center_vertical" >
</TextView>
<TextView
android:layout_width="100dp"
android:layout_height="200dp"
android:layout_gravity="top"
android:background="#drawable/border"
android:gravity="top"
android:text="layout_gravity=top gravity=top" >
</TextView>
</LinearLayout>
And here is the same code but for a vertical layout. Notice that the desired behavior works correctly in the vertical layout.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="200dp"
android:layout_height="100dp"
android:layout_gravity="left"
android:background="#drawable/border"
android:gravity="center_horizontal"
android:text="layout_gravity=left gravity=center_horizontal" >
</TextView>
<TextView
android:layout_width="200dp"
android:layout_height="100dp"
android:layout_gravity="right"
android:background="#drawable/border"
android:gravity="right"
android:text="layout_gravity=right gravity=right" >
</TextView>
</LinearLayout>
I can just use a RelativeLayout or maybe another nested LinearLayout to fix the problem. But I am asking this question because I would like to know if I am not understanding how gravity and layout_gravity works!! It is important to me that I understand how these fundamental attributes work. Thanks
If you want one centered and one top then you need to add a baseline aligned flag to the LinearLayout
android:baselineAligned="false"
It is default for the layout to align the children's baselines. This can cause issues such as this when the children use different values of gravity.
The difference with vertical is that the baselines can't be aligned as they can in horizontal.
See:
http://developer.android.com/reference/android/widget/LinearLayout.html#attr_android:baselineAligned
Additional info - This appears to explain the issue better than I can:
http://www.doubleencore.com/2013/10/shifty-baseline-alignment/
if you are trying something not "connected to each other" i.e. you want some space between two widgets then use a blank widget and use weights
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="100" >
<TextView
android:layout_width="100dp"
android:layout_height="200dp"
android:layout_weight="40"
android:gravity="center_vertical"
android:text="layout_gravity=top gravity=center_vertical" >
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="20" />
<TextView
android:layout_width="100dp"
android:layout_height="200dp"
android:layout_weight="40"
android:gravity="right"
android:text="layout_gravity=top gravity=top" >
</TextView>
</LinearLayout>
You werent clear about the output that you wanted , this is what i could interpret as your required output.. But i will explain you how this works ..
For more on weights you can go to http://developer.android.com/reference/android/widget/package-summary.html
There is something called as "widget" and "content of widget"
While talking of linearlayout with layout_gravity you set gravity of it self as a "widget" in the main View and with gravity you set gravity to the content in that linearlayout
Simmilarly with say textview , if you use layout_gravity (say equal to center) then the textview will be centered in its space (i.e. it will be centered in its width if layoutorientation is vertical , and it will be centered in its height if layout_orientation is horizontal)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:text="Second Activity" />
</LinearLayout>
See the same in vertical orientation
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:text="Second Activity" />
</LinearLayout>
Also now see about the gravity when you apply gravity to textview, the "TEXT" in the textview is centered (if gravity=center)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
**android:gravity="center"**
android:text="Second Activity" />
</LinearLayout>
Now you can realise that gravity sets the gravity to the content within the widget.. the "content" of a widget can be widgets itself..
LinearLayout is a widget , and within linear layout you add yet other types of widgets (button and text view)
So applying gravity=center to textview sets its content(i.e. text)at the center and applying gravity to linearlayout will center its content(i.e. textview) at the center
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:gravity="center"
android:text="Second Activity" />
</LinearLayout>
gravity is how the view itself positions its content within the area determined by its width and height. layout_gravity is how the parent view positions the child within the parent's area. Usually you can simply set gravity on the LinearLayout instead of setting layout_gravity on all of its children.
Do note that for LinearLayouts, gravity only has an effect on the axis that is not the orientation, e.g. top and bottom would be relevant to a horizontal LinearLayout, but left and right (or start and end) would not be relevant.
In this layout I have two Views - the ImageButton at bottom right and the TextView at center bottom. When android:visibility of both of views is set to visible - all is aligned as needed. But if I set android:visibility for ImageButton to gone - EditText goes to the left edge of layout.
Questions:
1) Why it is happening so?;
2) How to achieve not changing place of EditText on setting ImageButton visibility to gone? I need to get the same layout as on the left picture (see below), but without ImageButton. (I know, one possibility would be setting visibility not to gone, but to invisible, but I'm more interested in the solution with visibility = "gone")
P.s.: The first two layouts - RelativeLayout and FrameLayout are mandatory - they are used for other stuff, I just removed all that is not related to question.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/mForSearchFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/mForAdMediation"
android:layout_alignWithParentIfMissing="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/mSearchEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:ems="5"
android:imeOptions="actionSearch"
android:inputType="text"
android:visibility="visible" >
<requestFocus />
</EditText>
<ImageButton
android:id="#+id/mSearchButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#drawable/dark_button"
android:src="#drawable/tab_search"
android:visibility="visible" />
</RelativeLayout>
</FrameLayout>
</RelativeLayout>
Here are layouts:
The problem is that your inner RelativeLayout is inside of a FrameLayout that is set to wrap_content for the width. So, when the ImageView goes away, the width of the RelativeLayout shrinks to the width of the EditText. So, the EditText is still centered within the RelativeLayout, but the RelativeLayout is only as wide as the EditText.
Maybe you could simplify your layout something like this?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/mSearchEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:ems="5"
android:imeOptions="actionSearch"
android:inputType="text"
android:visibility="visible" >
<requestFocus />
</EditText>
<ImageButton
android:id="#+id/mSearchButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#drawable/dark_button"
android:src="#drawable/tab_search"
android:visibility="visible" />
</RelativeLayout>
Hmm, It seems I found a solution:
I need to set layout_width of first FrameLayout to "match_parent"