I have this view ->
The view is setup basically like this
LinearLayout -orientation horizontal - Height (wrap)
LinearLayout -orientation vertical - Height (wrap) - weight .65
TextView
RecyclerView
LinearLayout - orientation vertical - Height (matchparent) - weight .35
TextView
TextView
TextView
In most cases the 1st LinearLayout (the left one) would determine the size in height because the RecyclerView would usually have more than 1 entry. But in the case of the image the 1st row this logic doesn't work. If I set the LinearLayout to the right as wrap, then when the left one is bigger then there is white around the gray background. What is the best way to achieve the 2nd layout is always the same height as the its parent and if the parent is too small the parent adjusts to it.
here is the full xml as requested
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginBottom="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent" android:layout_height="wrap_content">
<ProgressBar android:id="#+id/progressBar" android:layout_width="wrap_content" android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".65"
android:orientation="vertical"
android:padding="#dimen/activity_horizontal_margin">
<TextView
android:id="#+id/tv_organization"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
tools:text="Duke Hospital"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/availablehours"
android:textAppearance="#android:style/TextAppearance.Small"/>
<TextView
android:id="#+id/rv_available_hours"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:padding="0dp"
android:paddingBottom="4dp"
android:textAppearance="#android:style/TextAppearance.Small"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".35"
android:background="#color/offWhite"
android:gravity="center"
android:orientation="vertical"
android:paddingEnd="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingStart="#dimen/activity_horizontal_margin">
<TextView
android:id="#+id/tv_notavailable"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textAppearance="#style/TextAppearance.AppCompat.Subhead"
android:textColor="#color/darkerGreyColor"
android:visibility="gone"/>
<TextView
android:id="#+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAppearance="#style/TextAppearance.AppCompat.Display1"
android:textStyle="bold"
tools:text="30"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textAllCaps="true"
android:layout_gravity="center_horizontal"
android:text="#string/abbrev_min"/>
<TextView
android:id="#+id/tv_labelDuration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/estimatedwaittime"
android:textAppearance="#style/TextAppearance.AppCompat.Caption"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</android.support.v7.widget.CardView>
You can set the minHeight of
LinearLayout -orientation vertical - Height (wrap) - weight .65
so that right side text won't get clipped
Related
I have a RecycleView where i add items vertically:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:gravity="top">
<android.support.v7.widget.RecyclerView
android:id="#+id/contrattiRecycle"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|center"
android:layout_weight="1"/>
</LinearLayout>
and the itemcontainer is like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:id="#+id/ore"
android:layout_weight="1"
android:foregroundGravity="center"
android:gravity="center_horizontal"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:id="#+id/contratti"
android:layout_weight="1"
android:gravity="center_horizontal"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:id="#+id/resa"
android:layout_weight="1"
android:gravity="center_horizontal"/>
</LinearLayout>
When i fill the RecycleView with items they won't align properly but appear like the picture below:
The RecycleView is filled in a normal way. As long as every layout width is: android:layout_width="match_parent" it should expand this layouts to the parents width and the items logically should be aligned. Any suggestion?
android:layout_weight="1"
as you use the layout_weight property,if you set android:layout_width="wrap_content",The system first assigns the three textviews their width wrap_content (wide enough to contain their content), and then assigns the remaining screen space to the three textviews according to the ratio of 1:1:1,so your content is not the same width, it will not appear aligned.
you just need to change TextView
android:layout_width="wrap_content"
to
android:layout_width="0dp"
in this case,it will divide the width by 1:1:1 first
For both the linear layouts and text views make:
android:layout_gravity="center"
android:gravity="center"
not center_vertical or center_horizontal
I am working on a project. I am required to make a TextView to be fit into 1 line (as shown below).
But after I tried adjusting layout_weight, it fails.
Here is my code (with original layout_weight):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tool="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/view_toolbar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/appbar"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="25dp">
(omitted)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/padding_small"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:textAppearance="?android:attr/textAppearanceListItemSmall">
<TextView
android:id="#+id/hose_expired_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="#dimen/padding_x_larger"
android:layout_weight="1"
android:textColor="#color/textColor_dark"
android:textSize="#dimen/font_size_medium" />
<TextView
android:id="#+id/hose_expired_count_amount"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/padding_larger"
android:layout_weight=".5"
android:textColor="#color/textColor_dark"
android:textSize="#dimen/font_size_medium" />
</LinearLayout>
(omitted)
</LinearLayout>
(omitted)
</LinearLayout>
</RelativeLayout>
How can I fix the layout_weight (and possibly width, height, etc.) so that I can get the TextView fitted?
How about you don't use weights for the hose_expired_count_amount TextVIew. Just use wrap_content for the width and don't add any weight. Your "Hose Expired" text will fill the space.
<TextView
android:id="#+id/hose_expired_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="#dimen/padding_x_larger"
android:layout_weight="1"
android:textColor="#color/textColor_dark"
android:textSize="#dimen/font_size_medium" />
<TextView
android:id="#+id/hose_expired_count_amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/padding_larger"
android:textColor="#color/textColor_dark"
android:textSize="#dimen/font_size_medium" />
</LinearLayout>
If you want the text to be directly beside each other, you'd need to right-align your hose_expired_count TextView by setting the gravity as right/end
Just use wrap_content for width of hose_expired_count_amount
I'd like to set the layout_weight of the TextView with the tv_long_text to 80% in the following LinearLayout of vertical orientation.
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tv_short_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
tools:text="short text" />
<TextView
android:id="#+id/tv_long_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="0.8"
tools:text="a pretty long text" />
</LinearLayout>
The above is not working because the orientation of the textview's parent is vertical.
So, I tried to set the android:layout_width="match_parent" in the xml and then set the width at run time by getting the measured width and then sets the width to 80% but the getMeasuredWidth is giving me 0.
int measuredWidth = longTextView.getMeasuredWidth();
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) longTextView.getLayoutParams();
params.width = (int) (measuredWidth * 0.8);
longTextView.setLayoutParams(params);
I also tried to set the layout_weight at run time but it didn't work either and it's probably because it's parent view is in vertical orientation.
longTextView.setLayoutParams(
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.MATCH_PARENT,
0.8f)
);
The one that worked for me is by adding some extra views for the long text view. But it's 2 more extra views added for just trying to set the width of this view in percentage. Is there any other efficient way to do this?
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tv_short_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
tools:text="short text" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tv_long_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="0.8"
android:textStyle="bold"
tools:text="a pretty long text" />
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.2"/>
</LinearLayout>
</LinearLayout>
I would not try to fiddle with run time measurements. Your solution with a second horizontal Layout is perfectly fine since you have two TextViews expanding horizontally.
Another option would be PercentRelativeLayout from the support library com.android.support:percent:25.1.0 See here
This is from the docs
<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">
<ImageView
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
app:layout_marginTopPercent="25%"
app:layout_marginLeftPercent="25%"/>
</android.support.percent.PercentRelativeLayout>
use android:layout_weight
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<android.support.v4.widget.Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"/>
</LinearLayout>
TRY This structure to let TextView flow only upto 75% of the screen width.
you can adjust SPACER width to achieve, what you want like 2 for 50%.
You can use android:weightSum, and achieve the same result without additional View like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10"
android:orientation="vertical">
<TextView
android:id="#+id/tv_short_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
tools:text="short text" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10">
<TextView
android:id="#+id/tv_long_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="8"
android:textStyle="bold"
tools:text="a pretty long text a pretty long text a pretty long text" />
</LinearLayout>
</LinearLayout>
Solution with ConstraintLayout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/selector_rect_white_gray">
<TextView
android:id="#+id/tv_short_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="short text" />
<TextView
android:id="#+id/tv_long_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_short_text"
app:layout_constraintWidth_percent=".8"
tools:text="very long text - 80% of screen width exact" />
</androidx.constraintlayout.widget.ConstraintLayout>
I'm new to Android development. I've searched and tried almost everything that I've found but I couldn't managed to create the layout below. Basiciliy it'll be rows with background image and text middle-left aligned. I want all rows to be static height and background image to be covered (like this: css).
It's not very clear but you could try a LinearLayout (vertical) with inside
a RelativeLayout with fixed height for each items. In RelativeLayout aa
ImageView with match_parent for background of item with scale type at center and a TextView for text with padding:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="100dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/btn_alert_1"
android:scaleType="center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blabla"
android:textColor="#android:color/holo_green_dark"
android:paddingLeft="50dp"
android:paddingTop="40dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="100dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/btn_alert_2"
android:scaleType="center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blabla"
android:textColor="#android:color/holo_green_dark"
android:paddingLeft="50dp"
android:paddingTop="40dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="100dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/btn_alert_1"
android:scaleType="center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blabla"
android:textColor="#android:color/holo_green_dark"
android:paddingLeft="50dp"
android:paddingTop="40dp"/>
</RelativeLayout>
</LinearLayout>
Documentation about Android scale type: https://developer.android.com/reference/android/widget/ImageView.ScaleType.html
I tried many times to draw 2 Relative layout aligned horizontally and divided in half screen.
I design the image with paint to explain a bit better what i mean.
Any suggestion?
Another way to accomplish the same task without needing to use a LinearLayout is to put a center-aligned "shim" in the middle of the parent layout, then align other elements to it. If you set the half-width element's width to match_parent, but align both their left and right sides, they'll end up shrinking themselves to fit.
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.EqualWidthExample" >
<!-- An invisible view aligned to the center of the parent. Allows other
views to be arranged on either side -->
<View
android:id="#+id/centerShim"
android:layout_height="match_parent"
android:layout_width="0dp"
android:visibility="invisible"
android:layout_centerHorizontal="true"/>
<!--Set width to match_parent sets maximum width. alignParentLeft aligns
the left edge of this view with the left edge of its parent. toLeftOf
sets the right edge of this view to align with the left edge of the
given view. The result of all three settings is that this view will
always take up exactly half of the width of its parent, however wide
that may be. -->
<Button
android:id="#+id/btLeft"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/centerShim"
android:text="Left Button" />
<!--Same deal, but on the right -->
<Button
android:id="#+id/btRight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/centerShim"
android:layout_below="#+id/tvLeft"
android:text="Right Button" />
</RelativeLayout>
You can put these 2 RelativeLayouts inside a LinearLayout with horizontal orientation, then use the weight for both RelativeLayouts. This will divide the LinearLayout in 2 equal parts.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
</RelativeLayout>
</LinearLayout>
now you can do it easily using PercentRelativeLayout
<android.support.percent.PercentRelativeLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<Button
android:id="#+id/button"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="Button"
app:layout_widthPercent="50%"/>
<Button
android:id="#+id/button2"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/button"
android:text="Button 2"
app:layout_widthPercent="50%"/>
</android.support.percent.PercentRelativeLayout>
don't forget to add the gradle dependency
dependencies {
compile 'com.android.support:percent:25.3.1'
}
code in github
Update
PercentRelativeLayout is Deprecated since API level 26.0.0
You could use an non-recommended structure with nested wieghts
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:baselineAligned="false"
android:weightSum="5">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:layout_gravity="center">
<TextView
android:id="#+id/TopTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Top Text View"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"/>
</RelativeLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:weightSum="2"
android:layout_weight="4">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/LeftTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Left Text View"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/RightTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Right Text View"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
I see 4 relativelayouts in your drawing...?
If you mean the two in the middle put them into one LinearLayout (horizontal orientation), let all of them have a width of match_parent and give both relative layouts a weight of 1