I have a Scrollview with a ConstraintLayout and I want to add some Imagebuttons. They should be scaled to fit the half width so I can put 2 Buttons in a row.
The whole thing must me scrollable because I want to add about 10 rows of buttons.
I tried many options like seen here ConstraintLayout: how to have a view be half the screen width and centered?
My layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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="wrap_content"
android:layout_height="wrap_content"
android:fillViewport="true"
tools:ignore="SpeakableTextPresentCheck">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:adSize="BANNER"
app:adUnitId="ca-app-pub-xxxxxx"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/ibDog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/dog"
app:layout_constraintEnd_toStartOf="#+id/ibHorse"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/adView"
app:srcCompat="#drawable/dog" />
<ImageButton
android:id="#+id/ibHorse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/horse"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/ibDog"
app:layout_constraintTop_toBottomOf="#+id/adView"
app:srcCompat="#drawable/horse" />
<ImageButton
android:id="#+id/ibCat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/cat"
app:layout_constraintEnd_toStartOf="#+id/ibFrog"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/ibHorse"
app:srcCompat="#drawable/cat" />
<ImageButton
android:id="#+id/ibFrog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/frog"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/ibCat"
app:layout_constraintTop_toBottomOf="#id/ibHorse"
app:srcCompat="#drawable/frog" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
Thanks!
Try the following. I have changed the width of the ScrollView to match_parent and changed the width of the ImageViews to 0dp which will stretch out the images according to chain logic.
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
tools:ignore="SpeakableTextPresentCheck">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/adView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:adSize="BANNER"
app:adUnitId="ca-app-pub-xxxxxx"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/ibDog"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="#+id/ibHorse"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/adView"
app:srcCompat="#drawable/ic_launcher_foreground" />
<ImageButton
android:id="#+id/ibHorse"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/ibDog"
app:layout_constraintTop_toBottomOf="#+id/adView"
app:srcCompat="#drawable/ic_launcher_foreground" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="#+id/ibHorse"
android:layout_width="0dp"
android:layout_weight="1"
android:contentDescription="#string/dog"
android:layout_height="wrap_content"
app:srcCompat="#drawable/horse" />
<ImageButton
android:id="#+id/ibCat"
android:layout_width="0dp"
android:layout_weight="1"
android:contentDescription="#string/cat"
android:layout_height="wrap_content"
app:srcCompat="#drawable/cat" />
</LinearLayout>
Related
I have a sample view, where on the top is logo + header divider + some description, and from the bottom starts: Button + some checkboxes, please see image below:
It looks good on current devices, but on old phones, when screen is small (5 inches for example) - elements overlap:
View looks like below:
<androidx.constraintlayout.widget.ConstraintLayout android:id="#+id/parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- TOP -->
<ImageView
android:id="#+id/logo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="#drawable/loremipsum"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.12"
app:layout_constraintWidth_percent="0.50"
tools:ignore="ContentDescription" />
<ImageView
android:id="#+id/divider"
android:layout_width="match_parent"
android:layout_height="15dp"
android:scaleType="fitXY"
android:src="#drawable/header_divider"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/logo"
tools:ignore="ContentDescription" />
<TextView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="text"
android:lines="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/divider"
android:textStyle="bold" />
<!-- BOTTOM -->
<LinearLayout
android:id="#+id/linearLayoutMobile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toTopOf="#+id/validIDLinearLayout"
android:orientation="vertical"
android:gravity="bottom"
android:visibility="visible">
<LinearLayout
android:id="#+id/linearLayoutMobilePhonePicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:visibility="visible">
<com.hbb20.CountryCodePicker
android:id="#+id/countryCodePickerId"
...
/>
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/mobileEditText"
android:layout_width="fill_parent"
android:hint="elo elo elo"
android:inputType="phone" />
</LinearLayout>
<TextView
android:id="#+id/mobileText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/fragment_terms_and_condition_send_sms" />
</LinearLayout>
<LinearLayout
android:id="#+id/validIDLinearLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:gravity="center_vertical"
app:layout_constraintBottom_toTopOf="#+id/consentLinearLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textViewValidIdBottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/errorRed"
android:text="text" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/consentLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#id/privacyPolicyLinearLayout"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="32dp"
android:gravity="center_vertical"
android:background="#color/errorRed"
app:layout_constraintEnd_toEndOf="parent" >
<TextView
android:id="#+id/textViewConsent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/fragment_terms_and_condition_consent_VI" />
</LinearLayout>
<LinearLayout
android:id="#+id/privacyPolicyLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:gravity="center_vertical"
app:layout_constraintBottom_toTopOf="#id/button_continue"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="#color/errorRed"
android:orientation="horizontal">
<TextView
android:id="#+id/textViewPrivacyPolicy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:linksClickable="true"
android:textColor="text"
android:text="#string/fragment_terms_and_condition_privacy_policy" />
</LinearLayout>
<TextView
android:id="#+id/button_continue"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:enabled="false"
android:background="#color/errorRed"
android:gravity="center"
android:text="ELO"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginBottom="80dp"
android:layout_marginTop="25dp"
app:layout_constraintWidth_percent="0.7" />
</androidx.constraintlayout.widget.ConstraintLayout>
How should I set constraint between this two parts of the view, so they wont overlap on small screen? Add marginTop to the bottom section?
I found an answer, will post below, maybe it helps someone in the future:
I copied all elements from Bottom section inside ScrollView:
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#+id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:fillViewport="true" >
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp" >
<!-- all LinearLayout's from bottom section -->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
I have a Seekbar with a LinearLayout of icons above it. I'm using LinearLayout weightsum and weight to align each one, however they are still not quite aligned.
Is there a way to align them?
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorWhite"
android:orientation="vertical">
<LinearLayout
android:id="#+id/test_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="5"
app:layout_constraintEnd_toEndOf="#+id/seekbar"
app:layout_constraintStart_toStartOf="#+id/seekbar"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
</LinearLayout>
<SeekBar
android:id="#+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="4"
android:theme="#style/Widget.AppCompat.SeekBar.Discrete"
android:thumb="#drawable/ic_black_navigation_24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/test_layout"
app:layout_constraintWidth_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
Edit:
I am aware that you can use
android:paddingStart="-16dp"
android:paddingEnd="-16dp"
to align them but I rather not prefer to use a set padding, because this causes readjusting the padding when you add another item.
e.g changing icons to 6, need to change weightsum to 6, and also need to set padding to -14dp.
It's hard maintain this with LinearLayout, so I used ConstraintLayout instead, and using the Guidelines to divide the width into 4 equal portions, then you can align the images to these guidelines.. This will be maintainable accross different device widths and screen orientation
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorWhite"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/test_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="#+id/seekbar"
app:layout_constraintStart_toStartOf="#+id/seekbar"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/iv0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="4dp"
android:paddingLeft="4dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.25" />
<ImageView
android:layout_width="wrap_content"
android:paddingStart="16dp"
android:paddingLeft="16dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="#+id/guideline1"
app:layout_constraintEnd_toEndOf="#id/guideline1"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="#id/guideline2"
app:layout_constraintStart_toStartOf="#+id/guideline2"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.75" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="16dp"
android:paddingRight="16dp"
app:layout_constraintEnd_toEndOf="#id/guideline3"
app:layout_constraintStart_toStartOf="#+id/guideline3"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="4dp"
android:paddingRight="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_black_trashcan_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<SeekBar
android:id="#+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="4"
android:theme="#style/Widget.AppCompat.SeekBar.Discrete"
android:thumb="#drawable/ic_black_navigation_24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/test_layout"
app:layout_constraintWidth_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
Result:
Portrait:
Landscape
I'm currently writing an android app with Android Studio. In order to fit most screen sizes I decided to use LinearLayouts inside ConstraintLayout.
I have the following code for xml:
<?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"
android:background="#color/colorBackground"
tools:context=".Kadr1Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="#string/contentDescrKadr1"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="#drawable/lol" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="#+id/backBtn"
style="#style/Widget.AppCompat.ImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="16dp"
android:adjustViewBounds="true"
android:background="#android:color/transparent"
android:contentDescription="#string/contentDescrNext"
android:onClick="nextClick"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:srcCompat="#drawable/btn_back" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<ImageButton
android:id="#+id/nextBtn"
style="#style/Widget.AppCompat.ImageButton"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="end"
android:layout_marginEnd="16dp"
android:adjustViewBounds="true"
android:background="#android:color/transparent"
android:contentDescription="#string/contentDescrNext"
android:onClick="nextClick"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:srcCompat="#drawable/btn_next" />
</LinearLayout>
</LinearLayout>
It looks like this:
I want ImageButtons height depend on the height of the ImageView. I tried using RelativeLayout, however, I cannot get how to implement dependencies not on whole screen size, but only on ImageView size.
So, how can I adjust height of my horizontal LinearLayout (with buttons) to be 4 times smaller (for example) than ImageView height?
Would be grateful for any possible advice.
Thanks to #Marcin Orlowski, I got it:
should set ImageView height to "0dp", horizontal LinearLayout height to "0dp", then set ImageView weight to "4" and LinearLayout weight to "1".
It works properly:
<?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"
android:background="#color/colorBackground"
tools:context=".Kadr1Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:adjustViewBounds="true"
android:contentDescription="#string/contentDescrKadr1"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="#drawable/lol" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1">
<ImageButton
android:id="#+id/backBtn"
style="#style/Widget.AppCompat.ImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="16dp"
android:adjustViewBounds="true"
android:background="#android:color/transparent"
android:contentDescription="#string/contentDescrNext"
android:onClick="nextClick"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:srcCompat="#drawable/btn_back" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<ImageButton
android:id="#+id/nextBtn"
style="#style/Widget.AppCompat.ImageButton"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="end"
android:layout_marginEnd="16dp"
android:adjustViewBounds="true"
android:background="#android:color/transparent"
android:contentDescription="#string/contentDescrNext"
android:onClick="nextClick"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:srcCompat="#drawable/btn_next" />
</LinearLayout>
</LinearLayout>
This question already has answers here:
View with minHeight in ConstraintLayout
(3 answers)
Closed 4 years ago.
I have created layout like this one
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/gray"
android:gravity="center"
android:padding="10dp"
android:text="top"
android:textColor="#color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/middle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/green"
android:gravity="center"
android:minHeight="300dp"
android:padding="10dp"
android:text="middle"
android:textColor="#color/white"
app:layout_constraintBottom_toTopOf="#id/bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/top" />
<TextView
android:id="#+id/bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/gray"
android:gravity="center"
android:padding="10dp"
android:text="bottom"
android:textColor="#color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
It does scroll on small screens as expected.
But on larger screens it leaves space below
How can I make layout match screen height, but still be scrollable on small screens?
Tried to set 'middle' height to 0dp, but this did not help.
Adding android:fillViewport="true" to ScrollView and set middle's height to 0dp solves the problem with space, but brings problem with scrolling - on small screens middle is shrinking, instead of scrolling.
Set the height of the middle TextView to 0dp (to match constraints) to fill the available space and add android:fillViewport="true" attribute to your ScrollView to stretch its content to fill the viewport.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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:fillViewport="true">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/gray"
android:gravity="center"
android:padding="10dp"
android:text="top"
android:textColor="#color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/middle"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/green"
android:gravity="center"
android:padding="10dp"
android:text="middle"
android:textColor="#color/white"
app:layout_constraintHeight_min="300dp"
app:layout_constraintBottom_toTopOf="#id/bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/top" />
<TextView
android:id="#+id/bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/gray"
android:gravity="center"
android:padding="10dp"
android:text="bottom"
android:textColor="#color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
</ScrollView>
The solution is to use app:layout_constraintHeight_min instead of android:minHeight
So this layout is correct
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:fillViewport="true">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/gray"
android:gravity="center"
android:padding="10dp"
android:text="top"
android:textColor="#color/white"
app:layout_constraintBottom_toTopOf="#id/middle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread_inside" />
<TextView
android:id="#+id/middle"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/green"
android:gravity="center"
android:padding="10dp"
android:text="middle"
android:textColor="#color/white"
app:layout_constraintBottom_toTopOf="#id/bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_min="300dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/top" />
<TextView
android:id="#+id/bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/gray"
android:gravity="center"
android:padding="10dp"
android:text="bottom"
android:textColor="#color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/middle" />
</android.support.constraint.ConstraintLayout>
I'm trying to utilize a ConstraintLayout (version 1.0.2) to set the height of 2 side-by-side views to match the tallest one of them. This serves as a ViewHolder in for a RecyclerView, where each TextView gets an arbitrary length of text...
If I set each to wrap_content, the shorter one will shrink.
If I set both to 0dp (match_contraints), both end up 0 height.
Here's the setup:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/id1"
android:layout_width="60dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/id2"/>
<TextView
android:id="#+id/id2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/id1"
app:layout_constraintEnd_toEndOf="parent"/>
</android.support.constraint.ConstraintLayout>
I suppose this is a bug, as "0dp" should act more like match_parent than actual 0 dp.
On iOS, by the way, the equivalent Auto Layout rules (of setting views' heights to match top and bottom of parent) produce the expected result.
Of course this is pretty simple using LinearLayout, but this layout plays part in a larger layout, and I'd like to trim the view hierarchy...
Answering, in case anyone is looking out for answer in future.
ConstraintLayout introduced Barrier in v1.1 to achieve one such functionality asked by the OP in the question
The above mentioned functionality can be achieved using below xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/id1"
android:layout_width="60dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="#+id/barrier"
app:layout_constraintVertical_bias="0.0"
android:text="#string/id1_text" />
<TextView
android:id="#+id/id2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="#+id/id1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="#+id/barrier"
app:layout_constraintVertical_bias="0.0"
android:text="#string/id2_text" />
<android.support.constraint.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="id1,id2" />
</android.support.constraint.ConstraintLayout>
This might help you.
<android.support.constraint.ConstraintLayout
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/tv_1"
android:layout_width="150dp"
android:layout_height="match_parent"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="#color/colorAccent"
android:gravity="center"
android:padding="#dimen/activity_vertical_margin"
android:text="sjdjhshdjhdjhsdgfjhgsdjfgjsdgfjsdgfhgdsjhfghs"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/tv_2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_2"
android:layout_width="150dp"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
android:gravity="center"
android:padding="#dimen/activity_vertical_margin"
android:text="sjdjhsjhd"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/tv_1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
This is tricky and slow, but it works.
The point is:
Add additional invisible same layout for measure height. This one has wrap_content height attribute, so it will stretch parent if it is big enough.
Set your visible layout height to 0dp, so it will fill rest of parent.
As you can see the capture below, we have two layouts. Hidden one is wrap_contents
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/view_1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="#DDDDDD"
android:text="#android:string/yes"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/view_2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/view_1_invisible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#DDDDDD"
android:text="#android:string/yes"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/view_2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/view_2"
android:layout_width="100dp"
android:layout_height="0dp"
android:background="#DDDDDD"
android:text="#android:string/httpErrorBadUrl"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/view_1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/view_2_invisible"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#DDDDDD"
android:text="#android:string/httpErrorBadUrl"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/view_1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I've managed to do this with LinearLayout
parent to be height = wrap content
children to be height = match parent
children width = 0 and same weight
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
>
<TextView
android:layout_weight="1"
android:id="#+id/id1"
android:layout_height="match_parent"
android:layout_width="0dp"
android:background="#color/green_400"
android:text="11"
android:textSize="50sp"
/>
<TextView
android:layout_weight="1"
android:id="#+id/id2"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:background="#color/cat_grey_lite"
android:text="2222222222"
android:textSize="50sp"
/>
</LinearLayout>
<TextView
android:id="#+id/txt_service_request_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#drawable/bg_rectangle_blue"
android:gravity="center"
android:padding="8dp"
android:text="#string/service_request_id"
android:textColor="#android:color/white"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/txt_service_request_status"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt_service_request_status"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#drawable/bg_rectangle_blue"
android:gravity="center"
android:padding="8dp"
android:text="#string/service_request_status"
android:textColor="#android:color/white"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="#+id/txt_service_request_id"
app:layout_constraintEnd_toStartOf="#+id/txt_service_request_desc"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/txt_service_request_id"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt_service_request_desc"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#drawable/bg_rectangle_blue"
android:gravity="center"
android:padding="8dp"
android:text="#string/service_request_desc"
android:textColor="#android:color/white"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="#+id/txt_service_request_id"
app:layout_constraintEnd_toStartOf="#+id/txt_service_request_cat"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/txt_service_request_status"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt_service_request_cat"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#drawable/bg_rectangle_blue"
android:gravity="center"
android:padding="8dp"
android:text="#string/service_request_cat"
android:textColor="#android:color/white"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="#+id/txt_service_request_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/txt_service_request_desc"
app:layout_constraintTop_toTopOf="parent" />