Edittext keeps scrolling to its position inside RecyclerView - android

Prerequisites
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarFadeDuration="2"
android:scrollbars="vertical|horizontal">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
recyclerview_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<...>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</LinearLayout>
another_recyclerview_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#drawable/divider_default_margin"
android:orientation="vertical"
android:showDividers="middle">
<...>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/anotherRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<...>
</LinearLayout>
edittext_item_layout.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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/formTextClearButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/textInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
<...>
</androidx.constraintlayout.widget.ConstraintLayout>
Problem description
I am adding at runtime a recyclerview_layout.xml to the container inside main_layout.xml. The recyclerview_layout.xml sometimes contains another_recyclerview_layout.xml, which has a RecyclerView that has multiple view types, one of which is represented by edittext_item_layout.xml. When the latter exists in another_recyclerview_layout.xml and recyclerview_layout.xml is populated with some other items, the whole layout has a weird scrolling behavior, at the time the user taps on one of the TextInputEditTexts. It's like it tries to snap to the focused TextInputEditText and the user cannot scroll away from that view anymore. (See gif below)
Scrolling bug
Already tried solutions
Setting android:focusable="true" and android:focusableInTouchMode="true" to the direct child of the NestedScrollView, as you can already see in recyclerview_layout.xml. Also tried to add these properties to all the other containers (cry)
Setting android:descendantFocusability="blocksDescendants" to the parent of anotherRecyclerView. This solution does not work weel for me, since I need the TextInputEditText to be fully functional.
Listening to SoftKeyboard events and clearing focus as soon as the keyboard hides. This solution rises 2 other issues:
loses scroll position
the layout is still buggy, if the user tries to scroll while the keyboard is visible
Libraries
ConstraintLayout: 2.0.4
RecyclerView: 1.2.0
Material: 1.2.1
Help!
I am running out of ideas, any help is highly appreciated. Thank you!

Related

Kotlin - Keep button sticky in AppBarLayout$ScrollingViewBehavior (in FragmentContainerView)

I have an issue with FragmentContainerView, it looks like this:
<androidx.fragment.app.FragmentContainerView
android:id="#+id/myFragment"
android:name="com.me.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
And in its fragment, I have a recycler view, and a button:
<RelativeLayout 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">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<Button
android:id="#+id/myBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:gravity="bottom|center" />
However, when I am scrolling, button is also moving up, even though I set up alignParentBottom. I believe the issue is in this line of code:
app:layout_behavior="#string/appbar_scrolling_view_behavior"
which is actually:
<string name="appbar_scrolling_view_behavior" translatable="false">com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior</string>
FragmentContainerView is used in CoordinatorLayout. Note that button is out of SwipeRefreshLayout, so it shouldn't be affected by scrolling the recycler view.
I want to keep it sticky, so it doesn't move when I scroll the screen.
Any ideas?

Failed making scrollable a ConstraintLayout in an Android Fragment

Recently I tried to create a fragment and the LinearLayout is bigger than the screen and I need to use the ScrollView. I've tried different ways reading other questions in Stackoverflow and I couldn't resolve the issue.
This is my XML Code:
<?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="wrap_content">
<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=".ui.configuration.ConfigurationFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="MissingConstraints">
<TextView
android:id="#+id/text_configuration_first_tittle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/configuration_first_title"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
Any idea?
Resolved... The scrollview was working.
I only need to add marginBotton with enough height size to considere the Botton Navigation Bar

Margin to the scrollbar only (not to recyclerview) on recyclerview

My recycler view lies under my toolbar, as you can see from the first picture. However, I have a scrollbar on the right side of it. I have to give a margin-top to this scrollbar. I have tried with giving style. And I know about clip padding with padding-top and padding-bottom, however, I need this exactly. Are there any ways to make it real?
This is my problem
The result that I want
P.S. I know that it is not the best practice. I would appreciate any help. It is one of my first questions, don't judge me so strong. :)
My main XML file
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/background1"
android:keepScreenOn="true"
tools:context=".ui.main.HomeActivity">
<androidx.viewpager.widget.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/pager" />
<include layout="#layout/toolbar_sura_detail" />
<include layout="#layout/player" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
My Fragment XML inside ViewPager
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="?attr/background1">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/kuranDetailList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isScrollContainer="false"
android:fitsSystemWindows="true"
android:scrollbarSize="2dp"
android:scrollbarThumbVertical="#drawable/thumbforrecycle"
android:scrollbars="vertical"
android:orientation="vertical" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Try using this structure in your main XML and add scrolling layout behaviour for ViewPager
<androidx.coordinatorlayout.widget.CoordinatorLayout...
<com.google.android.material.appbar.AppBarLayout...
<androidx.appcompat.widget.Toolbar...
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/pager"
app:layout_behavior = "com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>

How to create a SwipeRefreshLayout that only can be pulled outside the RecyclerView?

I want to create a layout that has for example the main layout is a vertical LinearLayout, inside it is a TextView and a wrapped RecyclerView. I want to add a SwipeRefreshLayout that only can be swiped outside the RecyclerView.
Here is the simple XML for this layout:
<?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="match_parent"
android:orientation="vertical"
android:padding="40dp"
tools:context=".fragments.warehouse.WHTabOne">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
android:textSize="18sp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Where should I put the SwipeRefreshLayout to make it only works for outside the RecyclerView?
Make SwipeRefreshLayout your root layout and put everything inside it. Example:
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout 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"
android:id="#+id/swipe_refresh_layout"
android:padding="40dp"
tools:context=".fragments.warehouse.WHTabOne">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
android:textSize="18sp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
What I was asking for is to prevent the SwipeRefreshLayout from starting when swiping on RecyclerView only, and swiping everywhere else activate SwipeRefreshLayout.
But I found that the RecyclerView is by default overrides SwipeRefreshLayout until it reaches the top of the RecyclerView then it start to activate SwipeRefreshLayout. I thought it won't work because my list was too short and could't notice that. Now that I've added more items to the list, it's clear. So basically, adding everything under SwipeRefreshLayout is the right thing by default it will make it in right way.

Layout nesting problems in Android

I have a scrollview which acts wierd when scrolling. I have to scroll twice before the scrollview starts scrolling. This below is how my nesting is done. Does this nesting look alright, or is it bad? I tried rearranging the layouts but I couldnt stop the "two-time" scrolling problem I have.
first layout: (this one is inside a constraint layout)
//views before
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/yahoo_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/cond_const"
android:id="#+id/scrollView2"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="#layout/scroll_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
//views after
Second layout:
<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"
xmlns:custom="http://schemas.android.com/tools"
android:id="#+id/scrollview3">
<android.support.constraint.ConstraintLayout
android:id="#+id/forecast_constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//all this layout-files views here
</android.support.constraint.ConstraintLayout>
</ScrollView>
EDIT:
maybe I am misunderstanding, but you want the screen to scroll in both directions?
if not, then don't nest a scrollview inside a scrollview.
Either is probably obsolete. removing your for now.
try just
<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"
xmlns:custom="http://schemas.android.com/tools"
android:id="#+id/scrollview">
<android.support.constraint.ConstraintLayout
android:id="#+id/forecast_constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//all this layout-files views here
</android.support.constraint.ConstraintLayout>
</ScrollView>

Categories

Resources