How to use the whole space when placing ConstraintLayout inside a NestedScrollView? - android

I'm trying to put a ConstraintLayout inside a NestedScrollView, but there is a line that separates the ConstraintLayout. I can't place anything underneath that invisible line. I have been trying for hours and can't find the issue.
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.core.widget.NestedScrollView
android:id="#+id/premium_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BFFFFFFF"
android:focusableInTouchMode="true"
android:tag="layout/fragment_premium"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".PremiumFragment">
<ImageView
android:id="#+id/launcher_id"
android:layout_width="185dp"
android:layout_height="185dp"
android:layout_marginTop="25dp"
android:layout_marginBottom="20dp"
android:contentDescription="TODO"
app:layout_constraintBottom_toTopOf="#+id/premium_text_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/launch_premium" />
<TextView
android:id="#+id/premium_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="220dp"
android:text="#string/launch_to_premium"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView2"
android:layout_width="383dp"
android:layout_height="196dp"
android:layout_marginTop="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/premium_text_id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>

With a little bit of messing around I was able to get what you are looking for. The key is to use android:fillViewport="true" in the NestedScrollView
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.core.widget.NestedScrollView
android:id="#+id/premium_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BFFFFFFF"
android:focusableInTouchMode="true"
android:fillViewport="true"
android:tag="layout/fragment_premium">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/launcher_id"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginTop="25dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/launch_premium" />
<TextView
android:id="#+id/premium_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/launch_to_premium"
android:textSize="24sp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/launcher_id" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView2"
android:layout_width="383dp"
android:layout_height="196dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/premium_text_id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>

You need to add a attribute android:fillViewport="true" in your NestedScrollView
<androidx.core.widget.NestedScrollView
android:id="#+id/premium_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BFFFFFFF"
android:focusableInTouchMode="true"
android:fillViewport="true" <-- add this
android:tag="layout/fragment_premium">
why?
fillViewport allows NestedScrollView to extend its height equals to the full height of the device screen height in the cases when the child of scroll view has less height.
this blog Will explain more about it.

Related

How to make SearchView always on top in NestedScrollView?

I need to fix the place of searchView to the top. Even if user scrolls searchView must stay on the top. My xml is like that:
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/colorOffWhite"
tools:context=".HomeFragment"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<SearchView
android:id="#+id/searchView"
android:background="#color/colorBorder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/horizontalCategoryRV"
android:layout_width="412dp"
android:layout_height="121dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/searchView" />
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="5dp"
android:gravity="center_vertical"
android:text="#string/recent_products"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/horizontalCategoryRV">
</TextView>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_dashboard_items"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
android:layout_marginBottom="70dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
How can I implement a solution for this? I tried it with toolbar but I don't know if it's right to do that in a fragment. (This is a fragment's layout and I'm on Kotlin)
you can try use property
android:iconifiedByDefault="false" on your XML

Vertical bias and guidlines are not working in recyclerview android

I want to use vertical bias to view always top but, I want to use guidelines to restrict the height on the screen. But If I used height wrap content it's not working until I set it to height 0dp. Does any better approach for this?
<?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/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recylerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="#+id/guidelines"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.9" />
</androidx.constraintlayout.widget.ConstraintLayout>
After adding #Ivo answer
<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/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_default="wrap"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.9" />
</androidx.constraintlayout.widget.ConstraintLayout>
but the problem is my last view is cutting
I'm not sure if I completely understand it but I think you actually want android:orientation="horizontal" instead of android:orientation="vertical" in your Guideline
EDIT:
try using 0dp and also adding app:layout_constraintHeight_default="wrap" to your recyclerview

how to put recyclerview on bottom of spinner

I was using Constraint layout in a fragment. I had set TopToBottomOf although it wasn't reaching to bottom.
<Spinner
android:id="#+id/filterSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewCallLog"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/filterSpinner" />
I had set it app:layout_constraintTop_toBottomOf="#+id/filterSpinner". I want to put recyclerView on bottom of Spinner. I want to achieve it without margin.
Seems like constraint layout isn't working in the page. Hence I am showing the whole 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_marginTop="30dp"
android:layout_height="match_parent"
tools:context=".fragment.DialerFragment">
<Spinner
android:id="#+id/filterSpinner"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewCallLog"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/filterSpinner" />
<com.futuremind.recyclerviewfastscroll.FastScroller
android:id="#+id/fastscroll_dialer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
app:fastscroll__bubbleColor="#5e64ce"
app:fastscroll__handleColor="#8f93d1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#id/recyclerViewCallLog"
app:layout_constraintTop_toTopOf="#+id/recyclerViewCallLog" />
</androidx.constraintlayout.widget.ConstraintLayout>
You just need to do 0dp height for RecyclerView. like below
<?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_marginTop="30dp"
android:layout_height="match_parent">
<Spinner
android:id="#+id/filterSpinner"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewCallLog"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/filterSpinner" />
<com.futuremind.recyclerviewfastscroll.FastScroller
android:id="#+id/fastscroll_dialer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
app:fastscroll__bubbleColor="#5e64ce"
app:fastscroll__handleColor="#8f93d1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#id/recyclerViewCallLog"
app:layout_constraintTop_toTopOf="#+id/recyclerViewCallLog" />
</androidx.constraintlayout.widget.ConstraintLayout>

How to add button in the bottom of recyclerview in constraint layout?

I am new to constraint layout and I am trying to add my button below recyclerview, but I am not able to do that in constraint layout.
How I can achieve this functionality in constraint layout.
I am also share image for better understanding.
Try this sample code:
<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="match_parent">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/button"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The important point is that the ListView's height must be 0 and app:layout_constraintBottom_toTopOf="#+id/button" and app:layout_constraintTop_toTopOf="parent" .
Try something like this:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/myButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/myButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

constraint to bottom but allow keyboard to cover the view

I have a view constrained to bottom of the parent. I also have text fields on top. how ever when the keyboard shows up, it will push bottom views up which will cover my text fields.
I have everything inside a scroll view, keyboard should cover the bottom view and I should be able to scroll to bottom to reach the bottom view.
Here is a simple example. I manually increased the height to reproduce the problem easier. I actually have more views, this is just for demonstration.
note that fillViewPort is also enabled.
<?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="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/edit_text_1"
android:layout_width="0dp"
android:layout_height="180dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="#+id/edit_text_2"
android:layout_width="0dp"
android:layout_height="180dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/edit_text_1" />
<View
android:id="#+id/bottom_view"
android:layout_width="0dp"
android:layout_height="160dp"
android:background="#color/grey_500"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
You just simply need to put the ScrollView inside a ConstraintLayout
like this:
<?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="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="0dp"
android:layout_height="180dp"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/edit_text_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:layout_width="0dp"
android:layout_height="180dp"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/edit_text_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/edit_text_1"/>
<View
android:layout_width="0dp"
android:layout_height="160dp"
android:id="#+id/bottom_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/edit_text_2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

Categories

Resources