0

My activity contains ViewPager2 in its layout.

<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="ru.telemonitor.signal.r2d2.multimeter.imsat.Fragments.Dialogs.CalibrateActivity">

    ...

    <LinearLayout
        android:id="@+id/ll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintTop_toBottomOf="@+id/calibrate_result"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent">

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/calibrate_steps_pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:layout_gravity="center"
            android:layout_margin="10dp"
            />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/calibrate_steps_tab_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            app:tabBackground="@drawable/tab_indicator_selector"
            app:tabGravity="center"
            app:tabIndicatorHeight="0dp"
            />


    </LinearLayout>
    

</androidx.constraintlayout.widget.ConstraintLayout>

That is how ViewPager2 initializes. Note that CalibrateProbesFragment has a different height than others.

private inner class CalibrateActivityPagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
        override fun getItemCount(): Int = 4

        override fun createFragment(position: Int): Fragment {
            return when (position) {
                0 -> CalibrateProbesFragment()
                1 -> CalibrateVoltageFragment()
                2 -> CalibrateCurrentFragment()
                3 -> CalibrateResistanceFragment()
                else -> Fragment()
            }
        }
    }

When the activity is created by Intent there are right height measurements.

enter image description here enter image description here

After that, I try to recreate the activity in its onActivityResult method after calling some other activity by startActivityForResult.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        val unmaskedRequestCode = requestCode and 0x0000ffff

        if (unmaskedRequestCode == ImsatActivity.PICK_DEVICE_REQUEST) {
            if (resultCode == RESULT_OK) {
                data?.let { data ->

                    val index = data.getIntExtra(DiscoverActivity.DEVICE_INDEX, -1)
                    if (index < 0) {
                        super.onBackPressed()
                        return
                    }

                    val available = AppController.getInstance().dataProviderService.discoveredDevices
                    if (available.size == 0) {
                        Toast.makeText(this, "Error: try reconnect", Toast.LENGTH_LONG).show()
                        super.onBackPressed()
                        return
                    }

                    if (available.size < index) {
                        super.onBackPressed()
                        return
                    }

                    val multimeterDevice = available[index]
                    val name = data.getStringExtra(DiscoverActivity.DEVICE_NAME)
                    if (name == null || name == "" || name != multimeterDevice.name) {
                        super.onBackPressed()
                        return
                    }

                    AppController.getInstance().dataProviderService.tryConnectDevice(multimeterDevice)

                    viewPager.setCurrentItem(0, false)
                    restart()
                }
            }
        }
        }

    private fun restart () {
       // startActivity(Intent.makeRestartActivityTask(this.intent?.component))
        recreate()
    }

As you can note I call viewPager.setCurrentItem(0, false) before recreate(). After activity reset all fragments inside viewpager have the same height as this first fragment(at the index 0).

enter image description here enter image description here

I use recreate because I want the activity to be at the same point in the back navigation queue but fully recreate its views. And mostly because that seems to be less code solution for that. I really don't want to write 100+ lines for custom recreation if it is possible to use standard Activity methods. Maybe there are some workarounds? Thank you.

OshiniRB
  • 578
  • 1
  • 7
  • 21
RomanKovalev
  • 852
  • 3
  • 10
  • 29
  • 1
    This is a bug of ViewPager2, a possible solution is to revert to ViewPager and FragmentPagerAdapter, and ignore the deprecation warning. – EpicPandaForce Oct 21 '21 at 10:23

1 Answers1

0

I don't know how to solve this. I just start a new activity by the Intent.

private fun restart () {
       // startActivity(Intent.makeRestartActivityTask(this.intent?.component))
//        recreate()
        val intent = Intent(this, CalibrateActivity::class.java)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
        startActivity(intent)
        finish()
    }
RomanKovalev
  • 852
  • 3
  • 10
  • 29