views-widgets-samples icon indicating copy to clipboard operation
views-widgets-samples copied to clipboard

Focus issue with EditTexts in Fragments when using ViewPager2

Open raranov opened this issue 5 years ago • 17 comments

Build: AI-191.8026.42.35.6010548, 201911150702,

AI-191.8026.42.35.6010548, JRE 1.8.0_202-release-1483-b03x64 JetBrains s.r.o, OS Windows 10(amd64) v10.0 , screens 1536x864

AS: 3.5.3; Android Gradle Plugin: 3.5.3; Gradle: 5.4.1; NDK: from local.properties: (not specified), latest from SDK: (not found); LLDB: pinned revision 3.1 not found, latest from SDK: (package not found); CMake: from local.properties: (not specified), latest from SDK: (not found), from PATH: (not found)

I have an activity with a ViewPager2 container that swaps between three fragments. Each fragment contains two EditTexts. I have disabled manual scrolling, and the user can only traverse the fragments via a continue button. The goal is for the app to automatically focus the first EditText on the screen when the user opens that screen. The issue is that instead of the EditText getting focus, the ViewPager itself is getting the focus, even though it is not focusable. To try to fix this issue, I tried having the edittext explicitly requestFocus() in the fragment itself, but this doesn't help (after the user presses continue on the first screen, he gets to the second screen and the first edittext has no cursor or focus) and leads to some interesting scrolling issues. When I debug, I see that the ViewPager container itself has the focus.

Here is the repo, it is the ViewPager2 bug branch: https://github.com/raranov/MyExperienceNew/tree/ViewPager2 ViewPager (1) does not have this issue.

Also, I tried to do a similar thing using straight recyclerview, and that also had similar focus issues. The details are here: https://stackoverflow.com/questions/59489756/issue-with-focus-behavior-when-using-edittexts-in-a-recyclerview

Thank you.

raranov avatar Jan 18 '20 18:01 raranov

I have also struggled with this issue! I used viewpager 1 to avoid that bug in my project. Here is a test project which reproduces this bug: https://github.com/CakeWalker1337/ViewPager2-bugreport It would be great, if you fix it:)

CakeWalker1337 avatar Apr 23 '20 03:04 CakeWalker1337

I have to use ViewPager2 in order to support Arabic locale as well. Is somebody looking into this issue?

shadabunique avatar May 29 '20 21:05 shadabunique

I have a similar problem when I use ViewPager2 with FragmentStateAdapter. When I do navigation first time on a fragment by setCurrentItem, I can focus on an EditText. But reselecting the fragment causes the issue. You need to tap on the EditText twice because the first tap won't focus on the field, but you can still input message from the keyboard.

In this situation, as a temporary solution, I can set offscreen page limit to 1. Still expecting a normal fix.

VyacheslavMartynenko avatar Jun 01 '20 08:06 VyacheslavMartynenko

Experiencing the same issue moving from fragment to fragment with edittext

HarunJr avatar Jun 19 '20 18:06 HarunJr

Same on view holder

FEvgenSON avatar Aug 01 '20 13:08 FEvgenSON

I have the same issue and i have to use viewpager2 for vertical scroll which is not supported in viewpager1

samgithiaka avatar Aug 07 '20 12:08 samgithiaka

Same issue when using edit text with fragments with viewpager2. Is there any work around?

Nikunj2505 avatar Nov 13 '20 13:11 Nikunj2505

Increase offscreen page limit

FEvgenSON avatar Nov 13 '20 14:11 FEvgenSON

I have the same issue.

Thanks to @FEvgenSON for the workaround, but I hope it will be fixed

schlagi123 avatar Jan 05 '21 12:01 schlagi123

Unfortunately increase offscreen page limit don't work for me

Ifans007 avatar Feb 19 '21 13:02 Ifans007

In my case the number of offscreenPageLimit should be not smaller the number of pages

Ifans007 avatar Feb 19 '21 15:02 Ifans007

There are 3 workarounds for this issue, all worked in my case:

  1. increase offsetScreenPageLimit, 1 is enough no matter how many pages i got;
  2. vp2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
  3. ((RecyclerView)vp2.getChildAt(0)).getLayoutManager().setItemPrefetchEnabled(false);

FeatherSeven avatar Jul 12 '21 03:07 FeatherSeven

Same issue here, is there a fix available ?

PembaTamang avatar Sep 17 '21 12:09 PembaTamang

There are 3 workarounds for this issue, all worked in my case:

  1. increase offsetScreenPageLimit, 1 is enough no matter how many pages i got;
  2. vp2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
  3. ((RecyclerView)vp2.getChildAt(0)).getLayoutManager().setItemPrefetchEnabled(false);

this didn't work for me

PembaTamang avatar Sep 17 '21 12:09 PembaTamang

Same issue here, is there a fix available ?

Hey, we solved this bug in the library called Fragula. I found out that transferring the ViewPager2 code to the project and commenting out the dispatchSelected method in the ScrollEventAdapter class solves it. If you're okay with transferring the library to your app, you might use this solution to fix the bug. Here's the commit: https://github.com/massivemadness/Fragula/pull/23/commits/61aca39074322cb24d0a44fc5cbed42657b36eea"

KitsuneFolk avatar Jul 14 '23 09:07 KitsuneFolk

  1. when editText is child of viewpager2,may try this
fun ViewPager2.setDescendantFocusabilityKtx(focusability:Int) {
    if (childCount > 0) {
        val rl = this.getChildAt(0)
        if (rl is RecyclerView) {
            rl.descendantFocusability = focusability
        }
    }
}

binding.viewPager.setDescendantFocusabilityKtx(ViewGroup.FOCUS_AFTER_DESCENDANTS)

2. when edittext is slibing node of viewpager2

fun ViewPager2.setIsFocusableInTouchModeKtx(isFocusableInTouchMode:Boolean){
    if (childCount > 0) {
        val rl = this.getChildAt(0)
        if (rl is RecyclerView) {
            rl.isFocusableInTouchMode = isFocusableInTouchMode
        }
    }
}
binding.viewPager. setIsFocusableInTouchModeKtx(false)



OoadaioO avatar Aug 03 '23 08:08 OoadaioO

Has ViewPager2 called the setPageTransformer() method? Please check if there are any issues with the overridden ViewPager2.PageTransformer. For example, like in the code below, does it require setVisibility(View.GONE)?

private const val MAX_ROTATION = 10.0f

class RotatePageTransformer : ViewPager2.PageTransformer {

override fun transformPage(page: View, position: Float) {
    page.apply {
        when {
            position <= 0 -> {
                setViewVisible()
                alpha = 1f
                pivotX = width / 2f
                pivotY = height * 1f
                rotation = position * MAX_ROTATION
                translationX = 0f
            }
            position <= 1 -> {
                alpha = if (position == 1f) {
                    //need gone
                    setViewGone()
                    0f
                } else {
                    setViewVisible()
                    (1 - position).coerceAtLeast(0.35f)
                }
                rotation = 0f
                translationX = -position * page.width
            }
            else -> {
                setViewVisible()
                alpha = 0f
                rotation = 0f
                translationX = 0f
            }
        }
    }
}

}

zhuhuan0122 avatar Nov 23 '23 06:11 zhuhuan0122