简体   繁体   中英

Android Activity recreation front ViewPager2 layout measurements

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.

在此处输入图片说明 在此处输入图片说明

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).

在此处输入图片说明 在此处输入图片说明

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.

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()
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM