Balancing horizontally 2 TextViews and an ImageView between them according to text length - android-layout

If Text1 is longer, than it should push everything to the right
If Text2 is longer, than it should push everything to the left
Otherwise, the arrow should be centered according to parent view
If any TextView exceeds, thus the whole view exceeds the parent view, then it should be trimmed (ellipsize)

You can achieve this using ConstraintLayout. Create a packed horizontal chain, and use wrap_content plus constrainedWidth on each text view:
<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">
<TextView
android:id="#+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/image"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constrainedWidth="true" />
<TextView
android:id="#+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constrainedWidth="true" />
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/left"
app:layout_constraintEnd_toStartOf="#id/right"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
If both text views have long text, you can control which one gets given space first by re-ordering the tags within the ConstraintLayout. This won't change how they're positioned; it will change only whether the left or right text stretches first.

Related

Design Android dev screen sizes

Hi I need some advice/help
I am designing a app for educational purposes, but battling with different screen sizes.
I am using Android studio to create the screen layouts.
What I did so far works well up and until a point.
I have tried to use constraint layout / Linear layout and relative layout but all have the same issues.
I create my main layout as normal, and then I create new layout resource files with the same activity name but with different densities.
But for some odd reason some of my test phones picks up the certain density layout but is completely out of proportion, even though it looks correct on the layout on the IDE but the minute it is ported to the phone its out.
What would be the best way to create layouts that can cater for all layouts?
here is an example of the layout I have
<?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="match_parent"
tools:context=".login.LoginActivity"
android:background="#drawable/background"
android:padding="10dp">
<TextView
android:id="#+id/tv_appName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="250dp"
android:layout_marginEnd="8dp"
android:text="#string/app_name"
android:textColor="#color/colorAccent"
style="#style/Base.TextAppearance.AppCompat.Headline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textAlignment="center"
android:textStyle="bold"
android:textSize="28dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="50dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_appName"
android:background="#drawable/input_shape"
android:padding="15dp"
android:textColorHint="#color/colorAccent"
android:textColor="#color/colorAccent"
android:id="#+id/edittext1"
android:singleLine="true"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="50dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/edittext1"
android:background="#drawable/input_shape"
android:padding="15dp"
android:textColorHint="#color/colorAccent"
android:textColor="#color/colorAccent"
android:id="#+id/edittext2"
android:singleLine="true"/>
<Button
android:id="#+id/btn_button1"
android:layout_width="134dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="#+id/edittext2"
app:layout_constraintTop_toBottomOf="#+id/edittext2"
android:background="#drawable/btn_shape"
android:text="Button 1"/>
<Button
android:id="#+id/btn_button2"
android:layout_width="134dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="#+id/edittext2"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="#+id/btn_button1"
app:layout_constraintTop_toBottomOf="#+id/btn_button1"
android:background="#drawable/btn_shape"
android:text="Button 2"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
I am pretty sure that you are using a fixed size for your views.
Never use a fixed size for a view. If you are using a ConstraintLayout then set the layout_width and layout_height of any view to either 0dp (which will make the view as big as it can be as long as it doesn't go past the constraints) or wrap_content (which will automatically make the view only the size it needs). On other layouts instead of using 0dp for making the view as big as it can be, use match_parent. wrap_content does the same thing in every layout.

Placing a horizontal helper in Constraint Layout to be at the bottom of a View with a set custom margin

How do I set it so that a horizontal helper in Constraint Layout is set to be at the bottom of a particular View with a margin of 16dp in between?
What I've tried (with horizontal Guideline):
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.30779755"
app:layout_constraintTop_toBottomOf="#id/view2" />
It doesn't actually care about the layout_marginTop and layout_constraintTop_toBottomOf attribute. If I erase the layout_constraintGuide_percent attribute, it goes haywire and sticks to the top of the parent.
EDIT
I created that Guideline because I have a View which acts as a "background" behind multiple Views. I was hoping to constrain this background View to the bottom of this Guideline with an offset of 16dp from the last vertically aligned View (from the multiple Views). I want this background View to have a height based on the last vertically aligned View from the multiple Views, i.e. the height is determined by the bottom of the view + a 16dp margin. If I constrain the bottom of said background View to the bottom of the last vertically aligned View and add a bottom margin, the background View instead retracts 16dp from the bottom of the last vertically aligned View.
I would use a Space widget with a height of 16dp and a top constrained to the bottom of the lowest view. The bottom of the background view can be constrained to the bottom of the Space view to visually create the margin as follows using 64dp to accentuate the margin:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_red_light"
app:layout_constraintBottom_toBottomOf="#id/space"
app:layout_constraintEnd_toEndOf="#id/view1"
app:layout_constraintStart_toStartOf="#id/view1"
app:layout_constraintTop_toTopOf="#+id/view1" />
<TextView
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Using a Space widget"
android:textColor="#android:color/white"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="#+id/view2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="view2"
android:textColor="#android:color/white"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view1" />
<Space
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="64dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view2" />
</androidx.constraintlayout.widget.ConstraintLayout>
I also mentioned using a Layer helper with a bottom padding of 16dp. Although this currently works with ConstraintLayout 2.0.0-beta3, I am not convinced that it should work, so use at your discretion. Here is how it looks again with a Layer using 64dp padding to accentuate the margin. You will need ConstraintLayout 2.0 or later.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.helper.widget.Layer
android:id="#+id/layer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_red_light"
android:paddingBottom="64dp"
app:constraint_referenced_ids="view2,view1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Using a Layer"
app:layout_constraintVertical_chainStyle="packed"
android:textColor="#android:color/white"
android:textSize="30sp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toTopOf="#+id/view2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="view2"
android:textColor="#android:color/white"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view1" />
</androidx.constraintlayout.widget.ConstraintLayout>

How do I create a ConstraintLayout with 2 fixed parts and 1 expandable?

On this topic, I've been going round in circles and have totally confused myself.
I want to create a layout which has 3 components, stacked vertically. The first should be at the top of the screen, and take up however much space it needs (this will increase and decrease as things in it are clicked). The third should be at the bottom and is a fixed size (Google Ads). The one in the middle should take up the remaining space.
I currently have (wrapped in a ConstraintLayout):
<android.support.constraint.ConstraintLayout
android:id="#+id/cl_create_chart"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/fragment_charts_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
... contents of layout ...
</ConstraintLayout>
<fragment
android:id="#+id/fragment_charts_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/cl_create_chart"
app:layout_constraintBottom_toTopOf="#+id/au_adView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout="#layout/fragment_charts_list" />
<com.google.android.gms.ads.AdView
android:id="#+id/au_adView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="bottom"
ads:adSize="SMART_BANNER"
ads:adUnitId="..."
ads:layout_constraintBottom_toBottomOf="parent"
ads:layout_constraintEnd_toEndOf="parent"
ads:layout_constraintStart_toStartOf="parent" />
I'm meant to add in some vertical weighting, right? But nothing I try is making any difference - the first bit is floating down the screen so there's blank space above it. Can someone either give me a quick answer or point me to a tutorial that explains how to achieve this? I've read the Android docs, but can't find anything that includes 'filling the leftover space'.
To fill the screen with your three views as you wish, do the following:
Top view: width="0dp" (fill screen width); height="wrap_content" (Will let it grow/shrink as needed)
Middle view: width="0dp"; height = "0dp" (Fill space within top/bottom constraints.)
Bottom view: width="0dp"; height="wrap_content" (Really a fixed size due to nature of the content)
Here is a demo of these concept. I changed a few things around, made a fragment into a generic View, for instance, but the concepts are the same.
And the XML for this image:
<android.support.constraint.ConstraintLayout 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.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cl_create_chart"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#+id/fragment_charts_list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/lorem_ipsum"
android:textSize="20sp" />
</android.support.constraint.ConstraintLayout>
<View
android:id="#+id/fragment_charts_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_light"
app:layout_constraintBottom_toTopOf="#+id/au_adView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/cl_create_chart" />
<com.google.android.gms.ads.AdView
android:id="#+id/au_adView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
I will also point out that you have "ads" as a namespace prefix when you need an "app" prefix for the constraint layout in the Adview.

Android How to position Items in a Toolbar

I understand the one of the advantages of the toolbar over the action bar is the ability to position and add items. However I cannot figure out how to position these items on the toolbar where I would like to. I have 6 items and i want three of the items aligned to the left a space in the middle and the other three aligned to the right.
Use a Space widget for this.
Add a LinearLayout inside your Toolbar. I am adding 6 TextViews inside this LinearLayout. You can, of course, change it according to your requirement.
Now to align 3 of the child views to the left and 3 to the right simply add a android.support.v4.widget.Space widget after the third child view and set it's layout_weight property to 1.
Here's the entire toolbar layout
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="item1"
android:padding="2dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="item2"
android:padding="2dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="item3"
android:padding="2dp"/>
<android.support.v4.widget.Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="item4"
android:padding="2dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="item5"
android:padding="2dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="item6"
android:padding="2dp"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
Hope this works as required for you.

How can I set my imageviews to fill linearlayout with equal spacing?

I have four image icons that I need to display with Imagebutton or Imageview. The problem is when I use the following code, they all are aligned left leaving an empty space to the right.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="4">
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="#drawable/sale"
android:layout_weight="1"/>
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="#drawable/shirt"
android:layout_weight="1"/>
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="#drawable/women"
android:layout_weight="1"/>
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="#drawable/technology"
android:layout_weight="1"/>
</LinearLayout>
How can I get them equally distributed on the linearlayout so that they fill the whole width?
I just managed to fix the issue. It seems I was needed to use android:layout_width"fill_parent" instead of android:layout_width="wrap_content". I tried this after #grwww suggested android:layout_gravity="fill" which was not the needed attribute. Then I got to learn about fill_parent

Resources