I want to insert fixed footer bottom of the screen and above should be content in scroll view I used below code but it's throwing exception ScrollView can host only one direct child
<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">
<data>
<variable
name="mainActivity"
type="com.example.footer.MainActivity" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ScrollView>
<TextView
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Try is, it might be what you're looking for
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- ScrollView can only contain 1 view inside-->
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/footer"
app:layout_constraintTop_toTopOf="parent">
<!-- Use LinearLayoutCompat or ConstraintLayout or layout any-->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- do some thing -->
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<TextView
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The main issue is that the constraints are not set correctly and changes to ScrollView layout_height and id are needed.
ScrollView requires an id android:id="#+id/scrollView"
and bottom constraint to be top of TextView layout_constraintBottom_toTopOf="#+id/footer"
TextView needs a top constraint to be bottom of ScrollView layout_constraintTop_toBottomOf="#+id/scrollView"
Another issue was the height of ScrollView needs to use "match_constraint" which is set like this in the code view of the layout: android:layout_height="0dp"
When a dimension is set to MATCH_CONSTRAINT, the default behavior is to have the resulting size take all the available space.
Here is the final layout updated with above suggestions:
<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">
<data>
<variable
name="mainActivity"
type="com.example.footer.MainActivity" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/footer">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</ScrollView>
<TextView
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/scrollView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Related
I have a problem related with my xml code. Here is a screenshot from my page: https://i.stack.imgur.com/M6kvA.jpg
In this photo you can see that the Text View which says "Popular Tv Series" is over the recycler view items. I want to position this textView above the recycler view so they dont't cover each other. Here is the xml code for both layout that i am using. I tried playing with the constraints but it just seems that the textView is fixed. Thanks!
fragment_search.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.SearchFragment.SearchFragment">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/edit_text_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="8dp"
app:endIconMode="clear_text"
app:startIconDrawable="#drawable/ic_search_bottomnav"
android:hint="#string/searchbar_hint"
app:boxStrokeColor="#color/dark_red"
>
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</com.google.android.material.textfield.TextInputLayout>
<View
android:id="#+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/light_gray"
android:layout_marginTop="20dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toBottomOf="#+id/edit_text_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/search_fragment_recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_view_recommended"
android:layout_marginTop="10dp"
/>
<TextView
android:id="#+id/text_view_recommended"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/divider"
android:layout_margin="10dp"
android:text="#string/searchFragment_mostPopular"
android:textStyle="bold"
android:textColor="#color/white"
android:textSize="23sp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
item_fragmentsearch_popular.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="#+id/movie_image"
android:layout_width="150dp"
android:layout_height="250dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:scaleType="fitXY"
android:layout_margin="5dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
1- Declare textview before recyclerview .
Assign height=0dp to recyclerview, contraints will automatically assign height to it.
Other Note: if you assign match parent width to any view then you dont need to write start to start and end to end contraint.
I'm creating a simple app for Android - RecyclerView, two Buttons and an EditText. Everything is OK except the EditText - it doesn't appear in the emulator, but it figures in the Design View. I tried different configurations - no luck.
Any help will be greatly appreciated. Thanks in advance,
Ad.
The code:
<?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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvA"
android:layout_width="411dp"
android:layout_height="652dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="88dp"
android:layout_height="0dp"
android:text="Button"
android:onClick="fur"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="#+id/button3"
android:layout_width="88dp"
android:layout_height="48dp"
android:onClick="ed"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button" />
<EditText
android:id="#+id/et1"
android:layout_width="200dp"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/rvA" />
</androidx.constraintlayout.widget.ConstraintLayout>
Try to set height of recycler view 0dp and bottom to top of buttons or editext 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvA"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/button"/>
<Button
android:id="#+id/button"
android:layout_width="88dp"
android:layout_height="48dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="#+id/button3"
android:layout_width="88dp"
android:layout_height="48dp"
android:text="Button3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button" />
<EditText
android:id="#+id/et1"
android:layout_width="200dp"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/rvA" />
</androidx.constraintlayout.widget.ConstraintLayout>
I try this on emulator and edittext is displaying fine.
So for some reason my scroll functionallity doesn't work after I implementet a SwipeRefreshLayout to my .xml
Why is that?
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:orientation="vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/PullToRefresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="false"
android:soundEffectsEnabled="false"
android:text="#string/PTRefresh"
android:textAllCaps="false"
android:textColor="#color/colorPullToRefresh"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipe_container"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/PullToRefresh"
app:layout_constraintVertical_bias="1.0">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="8"
android:fillViewport="true"
app:layout_constraintBottom_toTopOf="#+id/write"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
EDIT SOLUTION
<?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:orientation="vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipe_container"
android:layout_width="0dp"
android:layout_height="125dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/PullToRefresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center|top"
android:singleLine="false"
android:soundEffectsEnabled="false"
android:text="#string/PTRefresh"
android:textAllCaps="false"
android:textColor="#color/colorPullToRefresh"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.core.widget.NestedScrollView
android:id="#+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="45dp"
android:layout_weight="8"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/swipe_container" />
</androidx.constraintlayout.widget.ConstraintLayout>
It's happening because Android can't really tell the difference between a swipe to refresh and a swipe to scroll your ScrollView unless you use a NestedScrollView instead.
NestedScrollView was designed to handle exactly that type of scenario. It also works when you have a ScrollView inside another or a RecyclerView inside a ScrollView, and so on.
I have a SwipeRefreshLayout containing a RecyclerView for a chat activity. I have its bottom constrained to the top of a linear layout at the bottom of the screen:
<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_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/colorPrimaryDark"
android:paddingLeft="0dp"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="0dp"
android:paddingBottom="0dp"
tools:context="org.andrewedgar.theo.ChatRoomActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/listFooter"
app:layout_constraintBottom_toTopOf="#+id/listFooter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/chatRecyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
app:layout_constraintBottom_toTopOf="#+id/listFooter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</android.support.v4.widget.SwipeRefreshLayout>
<LinearLayout
android:id="#+id/listFooter"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#drawable/custom_border"
android:gravity="bottom"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<EditText
android:id="#+id/messageInput"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#android:color/transparent"
android:ellipsize="start"
android:gravity="center"
android:hint="#string/prompt_msg"
android:imeActionLabel="#string/action_send"
android:imeOptions="actionUnspecified"
android:inputType="textCapSentences|textAutoCorrect"
android:maxLines="2"
android:textColor="#color/white"
android:textColorHint="#color/hintColor"
android:importantForAutofill="no" tools:targetApi="o"/>
<ImageButton
android:id="#+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:contentDescription="#string/action_send"
android:padding="10dp"
android:src="#android:drawable/ic_menu_send" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
..but the SwipeRefreshLayout still takes up the whole screen and the messages appear behind the message input:
Is there a special type of constraint required for this to work?
Change the height of SwipeRefreshLayout to 0dp
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="0dp"
Why?
As per the documentation:
You can set the view size to a ratio such as 16:9 if at least one of
the view dimensions is set to "match constraints" (0dp).
Also
Note: You cannot use match_parent for any view in a ConstraintLayout. Instead use "match constraints" (0dp).
Need help at stretching my buttons in GridLayout so they would take all of the free space under the TextView
Here is my hierarchy
P.S. source code:
<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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/display"
android:layout_width="match_parent"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/display">
<Button
android:id="#+id/buttonOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/display" />
check if you are assigning the height and width in px, and change them to % (percentage).. is there any way you can show the source ?
P.S. this is how i fixed it.. i've changed it to Linear
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/re``s-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/display"
android:layout_width="match_parent"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<GridLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/display">
<Button
android:id="#+id/buttonOne"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/display" />
</GridLayout>