Button in the bottom of LinearLayout - android

I am making an app in which I have a RecyclerView. I have also added a button, but it isn't shown. See the left photo. What I now want is to make the RecyclerView so that may button is visible, like in the photo on the right. How can I achieve this?
Under the photos you can see my xml code. I'd like the RecyclerView to be relative/dynamic.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.test.MainActivity"
android:orientation="vertical"
android:background="#color/colorAccent">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar"/>
<androidx.cardview.widget.CardView
android:id="#+id/cardViewMiddle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
app:cardCornerRadius="15dp">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.core.widget.NestedScrollView>
</androidx.cardview.widget.CardView>
<Button
android:id="#+id/btnCheckout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/round_corner"
android:backgroundTint="#color/colorPrimaryDark"
android:elevation="16dp"
android:text="START"
android:textColor="#FFFFFF"
android:textStyle="bold" />
</LinearLayout>

The problem is that you set the CardView height to match_parent so it takes up the entire screen. It's best to use ConstraintLayout for these kinds of layouts, but you can also fix it with minimal effort like this:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.test.MainActivity"
android:orientation="vertical"
android:background="#color/colorAccent">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar"/>
<androidx.cardview.widget.CardView
android:id="#+id/cardViewMiddle"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_weight="1"
app:cardCornerRadius="15dp">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.core.widget.NestedScrollView>
</androidx.cardview.widget.CardView>
<Button
android:id="#+id/btnCheckout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/round_corner"
android:backgroundTint="#color/colorPrimaryDark"
android:elevation="16dp"
android:text="START"
android:textColor="#FFFFFF"
android:textStyle="bold" />
</LinearLayout>
Note I only changed CardView's layout_height to 0dp and then added the following:
android:layout_weight="1"
Which will tell the layout to stretch as much as it can (while not covering other elements below it).

Related

RecyclerView is always above other views

It seems to me that I have read all the topics on stackoverflow and have not found a solution.
The problem is that ImageView is always under RecyclerView, whatever I do, but I need to display ImageView on top of RecyclerView.
Question: Why is this happening and how can I fix it?
Example of right and wrong:
My XML:
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/bottom_style"
android:overScrollMode="never"
app:behavior_hideable="false"
app:behavior_peekHeight="150dp"
app:layout_behavior="....BottomSheetController.MyBottomSheetBehavior">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<....BottomSheetController.MyRecyclerView
android:id="#+id/recycler_view"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:overScrollMode="never" />
<ImageView
android:id="#+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_button_close" />
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>
Try below code
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/colorAccent"
android:overScrollMode="never"
app:behavior_hideable="false"
app:behavior_peekHeight="150dp"
app:layout_behavior="....BottomSheetController.MyBottomSheetBehavior">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<....BottomSheetController.MyRecyclerView
android:id="#+id/recycler_view"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:overScrollMode="never" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<ImageView
android:id="#+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:src="#drawable/ic_button_close" />
</RelativeLayout>
</androidx.core.widget.NestedScrollView>
Is there any specific reason why you need to wrap the content in RelativeLayout if not making use of a FrameLayout should fix your issue, remember to set android:layout_gravity="end|top" to position your close button on top-end. So the code looks something like below:
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/bottom_style"
android:overScrollMode="never"
app:behavior_hideable="false"
app:behavior_peekHeight="150dp"
app:layout_behavior="....BottomSheetController.MyBottomSheetBehavior">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<....BottomSheetController.MyRecyclerView
android:id="#+id/recycler_view"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:overScrollMode="never" />
<ImageView
android:id="#+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|top"
android:src="#drawable/ic_button_close" />
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>
As for the reason, from what I believe, why RelativeLayout was showing the incorrect output was because the the distance of views on z-axis is set based on the order they are generated. So even though the ImageView is set after recyclerview, to be on the Top, but the holders inside are generated afterwards and are therefore on top of the imageview.
If it was a simple view generated before the imageview, image would be on top as desired.
P.S.: I didn't find any documentation for this and is purely how I believe it works so if that is not the case anyone is free to correct me.
Try to add this code in your adapter
close = (ImageView) itemView.findViewById(R.id.close);
close.bringToFront();

How to make bottom navigation stay at the bottom in LinearLayout?

How can I make the bottom navigation to stay at the bottom of the page by using the LinearLayout? Most solution I found is they used RelativeLayout instead of LinearLayout.
Below is my code
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/purpleBoo"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=" MY ACCOUNT"
android:textStyle="bold"
android:textColor="#color/white">
</TextView>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/btm_nav"
app:itemIconTint="#color/bottom_nav_color"
app:itemTextColor="#color/bottom_nav_color"
app:menu="#menu/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/purpleBoo"
android:clipToPadding="false" />
</LinearLayout>
It is quite easy - your xml should look like this:
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/purpleBoo"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=" MY ACCOUNT"
android:textStyle="bold"
android:textColor="#color/white">
</TextView>
</androidx.appcompat.widget.Toolbar>
<!--Just add in between the action bar and bottom bar some other view with height = 0dp and weight = 1. I added one more LinearLayout-->
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/btm_nav"
app:itemIconTint="#color/bottom_nav_color"
app:itemTextColor="#color/bottom_nav_color"
app:menu="#menu/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/purpleBoo"
android:clipToPadding="false" />
</LinearLayout>
In other cases it won't work. There should be at least one weight but not height based view in LinearLayout to do it.
Hope it helps.

Strange behaviour of recyclerview in nestedscrollview

I have a layout like below. Problem is that the recyclerview height only shows one item.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="#dimen/activity_horizontal_margin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Live Transactions"
android:textStyle="bold"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/ic_refresh"
android:background="#android:color/transparent"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Strange thing is that when I change the attribute
app:srcCompat="#drawable/ic_refresh"
in the ImageButton to something like
app:srcCompat="#android:drawable/ic_menu_search"
the recyclerview height becomes normal most items show. The ImageButton is on a layout above RecyclerView. Why does this happen?
You have to make your inner linear layout as match parent
<android.support.v4.widget.NestedScrollView 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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Live Transactions"
android:textStyle="bold"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#mipmap/ic_launcher"
android:background="#android:color/transparent"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Solved it simply by adding
android:fillViewport="true"
to the NestedScrollView
Make the layout_height on the Recycler View to match_parent
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Unable to convert RelativeLayout to ConstraintLayout

I have the following code and I want to convert the RelativeLayout to be ConstraintLayout and want it to show exactly the same. However, The ViewPager tag doesn't settle in the center like expected. I want the following code to be in constraint layout but unable to achive it. I converted layout_above to layout_constraintTop_toTopOf and such but cannot make it work well. It would be lovely if you can share me some examples or tips! I would love to hear from you !
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="#drawable/d"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<View android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="1dp"/>
</LinearLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/footer"
android:layout_below="#id/header"
android:overScrollMode="never">
</androidx.viewpager.widget.ViewPager>
<LinearLayout
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<include layout="#layout/pagerlayout"/>
</LinearLayout>
</RelativeLayout>
If you just want a ConstraintLayout template with header and footer with a viewpager in between, then here ya go:
<?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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/footer"
android:layout_below="#id/header"
android:layout_marginTop="8dp"
android:overScrollMode="never"
app:layout_constraintBottom_toTopOf="#+id/footer"
app:layout_constraintTop_toBottomOf="#+id/header"></androidx.viewpager.widget.ViewPager>
<LinearLayout
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent">
<!-- include layout="#layout/pagerlayout"/ -->
</LinearLayout>
</android.support.constraint.ConstraintLayout>
You should be able to start from there and acheive what you want.
If you ask any follow up questions, they will be ignored because your question has so little information included that if would be unfair to do so.

AndroidX RecyclerView row height won't wrap

I've been using the new Androidx libraries and have run into an issue I cannot fix. I am using RecyclerView and just cannot get the row to wrap. It is supposed to do it, and everything I read seems to be that it just works if I cannot get it right. I have used this previously and did not have this issue. I've tried adjusting every setting in both my main layout and the item layout, but nothing seems to affect it. Any help would be appreciated.
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
xmlns:tools="http://schemas.android.com/tools">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/cardRecycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
android:clipToPadding="false"
app:spanCount="4"
android:orientation="vertical"
tools:listitem="#layout/item_card_preview"/>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/white"
app:titleTextColor="#color/colorSecondary" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
item.xml
<?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">
<data>
<variable
name="card"
type="com.jibmobile.clashroyaltoolkit.vo.CardPreview"/>
</data>
<ImageView
android:id="#+id/imageView"
image="#{card.name}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:paddingTop="0dp"
android:contentDescription="#{card.displayName}"
tools:src="#drawable/archers" />
OK in my case , in item.xml, the height was given "match_parent". After I converted it into "wrap_content", the recycle view height was expanded according to the number of items. Note that I am using the androidx library as well.
The item.xml code was like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:padding="#dimen/small_padding">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/tickred"
android:layout_marginStart="0dp"
android:layout_marginTop="1dp"
android:layout_gravity="top"
android:layout_marginEnd="#dimen/dimen_margin_between_text"/>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="#+id/serviceTv"
android:layout_gravity="top"
android:gravity="top"
app:fontFamily="#font/lato_regular"
android:textColor="#color/black"
android:textSize="#dimen/dimen_text_smallx"/>
</LinearLayout>
I changed the container height to wrap_content and the recycleview takes its height accordingly.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:padding="#dimen/small_padding">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/tickred"
android:layout_marginStart="0dp"
android:layout_marginTop="1dp"
android:layout_gravity="top"
android:layout_marginEnd="#dimen/dimen_margin_between_text"/>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="#+id/serviceTv"
android:layout_gravity="top"
android:gravity="top"
app:fontFamily="#font/lato_regular"
android:textColor="#color/black"
android:textSize="#dimen/dimen_text_smallx"/>
</LinearLayout>

Categories

Resources