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();
Related
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).
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" />
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.
I'm beginner in android, and I don't know why this happens.
Without SwipeRefreshLayout the RecyclerView is fully visible, but with SwipeRefreshLayout, the first item isn't shown.
Maybe it's under the toolbar? (The hidden item exists, I checked it in numerous ways.)
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipe_layout">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/MainRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
List:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="horizontal"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:weightSum="10"
android:gravity="center">
<ImageView
android:id="#+id/CharacterItemRankImageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_weight="0"
android:src="#drawable/challengemode_medal_bronze"/>
<TextView android:id="#+id/CharacterItemNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3.5"
tools:text="Name"/>
<TextView android:id="#+id/CharacterItemPointsTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:layout_weight="6"
tools:text="Points"/>
<ImageButton
android:id="#+id/CharacterItemRemoveButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_weight="0.5"
android:src="#drawable/ic_delete_grey600_48dp"
android:scaleType="fitXY" style="#style/Widget.AppCompat.Button.Borderless" />
</LinearLayout>
I guess you are using a CoordinatorLayout as root of your view. In that case, what is happenning is that the toolbar is being hidden by the first item of your RecyclerView.
To fix this issue, you just need to add the layout behavior to the SwipeRefreshLayout and remove from your RecyclerView.
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/MainRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
I have three recyclerviews in a single layout file which have horizontally aligned layoutmanagers and these recyclerviews are inside nestedscrollview and I've set the nestedscrolling for each of the three recyclerviews to false too.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="#+id/frameLayout"
android:background="#drawable/background">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="FREE MOVIES"
android:textStyle="bold"
android:textSize="18sp"
android:textColor="#color/colorAccent"
/>
<view
android:id="#+id/recycler_view"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="PREMIUM MOVIES"
android:textColor="#color/colorAccent"
android:textStyle="bold"
android:textSize="18sp" />
<view
android:id="#+id/recycler_view1"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<TextView
android:id="#+id/tvTrending"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="PACKAGES"
android:textColor="#color/colorAccent"
android:textStyle="bold"
android:textSize="18sp" />
<view
android:id="#+id/recycler_view2"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:dividerHeight="10.0sp" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<ProgressBar
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_gravity="center"/>
</FrameLayout>
And this is the layout of a fragment which I've called from a viewpager from MainActivity. Which has a layout like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
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.newitventure.musicnepal.MainActivity">
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/tabanim_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<include
android:id="#+id/tool_bar"
layout="#layout/toolbar" />
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
android:background="#color/colorPrimaryDark"
app:tabGravity="fill"
app:tabTextAppearance="#style/MyCustomTextAppearance"
app:tabMode="scrollable" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/tabanim_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<LinearLayout
android:id="#+id/gad_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:orientation="horizontal"
android:visibility="visible">
</LinearLayout>
</RelativeLayout>
The problem is while trying to scroll in this layout the scrolling is not smooth. It gets very laggy while trying to scroll both vertically and horizontally. What might be the issue here?
This has solved my problem:
mRecyclerView.setNestedScrollingEnabled(false);
For details :
Recyclerview inside ScrollView not scrolling smoothly
Okay,
I see three possibilities from the code given
1) You're using a RelativeLayout at the root for your views. While the RelativeLayout is awesome for a lot, it does have its drawbacks. Due to how RelativeLayout is built up it measures itself twice and all children in it. So for every frame currently displayed Android needs to recalculate every view twice.
2) You do have a "rather" deep structure on your views and I think that you for example can get rid of each of the 3 linear layouts you have around the pair of TextView and recycleview.
3) You're doing something heavy in the bindView method when displaying your recyclerviews.
Now all three of these could matter and play a role in making it laggy.
I would probably start with 2 (I don't think this alone will solve it completely, but it should improve the readability and speed of the code)
Then I would check for 3 (If you paste your code for the Adapter I could have a look on it if there's something clear there). If that still doesn't help try 1 (which can be hard as RelativeLayout is very good for structuring code)
Hope it helps!