Исключение Backstack ScrollView может содержать только один прямой дочерний элемент - PullRequest
0 голосов
/ 08 июня 2018

У меня есть простая настройка навигации по фрагментам:

<!-- Fragment container in activity that hosts fragments -->
<layout ...>

    <data>...</data>

    <android.support.v4.widget.DrawerLayout ...>

        <android.support.design.widget.CoordinatorLayout ...>

            <android.support.v4.widget.NestedScrollView
                android:id="@+id/container"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clipToPadding="false"
                android:fillViewport="true"
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />


            <android.support.design.widget.AppBarLayout ...>
                <android.support.v7.widget.Toolbar .../>
            </android.support.design.widget.AppBarLayout>

        </android.support.design.widget.CoordinatorLayout>

        <android.support.design.widget.NavigationView .../>

    </android.support.v4.widget.DrawerLayout>

</layout>



// and this function which replaces fragments
fun fragmentNavigation(fragment: Fragment?, enableBack: Boolean): Boolean {
    if (fragment != null) {
        val ft = supportFragmentManager.beginTransaction()
            .replace(R.id.container, fragment)

        if (enableBack) {
            // i use null value here because I don't need to 
            // go back to any specific point just to the last
            // fragment added to the back stack
            ft.addToBackStack(null) 
        }

        ft.commit()

        currentFragment = fragment
        return true
    }
    return false
}

Теперь проблема заключается в том, что когда я перемещаюсь к фрагменту и не добавляю его в стек, я ожидаю, что в навигационном менеджере кнопки «Назад» произойдет откат кпоследний фрагмент добавлен в задний стек, но вместо этого я получаю и исключение

// navigation to some other fragment
fragmentNavigation(CustomFragment.newInstance(), false)

// when I click back button I get crash on super.onBackPressed()
override fun onBackPressed() {
    return if (binding.drawer.isDrawerOpen(GravityCompat.START)) {
        binding.drawer.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed() // this line causes exception
    }
}

Вот исключение:

Process: com.domain.app, PID: 10938
java.lang.IllegalStateException: ScrollView can host only one direct child
at android.support.v4.widget.NestedScrollView.addView(NestedScrollView.java:406)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1434)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executePopOps(BackStackRecord.java:855)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2593)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:854)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:797)
at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:186)
at com.domain.app.home.HomeActivity.onBackPressed(HomeActivity.kt:113)
at com.domain.app.home.HomeActivity$onToggleBackButton$1.onClick(HomeActivity.kt:185)
at android.support.v7.app.ActionBarDrawerToggle$1.onClick(ActionBarDrawerToggle.java:204)
at android.view.View.performClick(View.java:6891)
at android.view.View$PerformClick.run(View.java:26083)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

1 Ответ

0 голосов
/ 08 июня 2018

Вы можете добавить FrameLyout в качестве дочернего элемента к NestedScrollView и использовать это FrameLyout в качестве контейнера.Так что представление фрагмента всегда будет добавлено к FrameLyout, а NestedScrollView будет иметь только одного прямого потомка.

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" >

    <FrameLayout 
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.v4.widget.NestedScrollView>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...