【问题标题】:ViewPager destroys fragment when orientation changeViewPager 在方向改变时破坏片段
【发布时间】:2017-10-25 17:10:45
【问题描述】:

我目前正试图理解为什么当屏幕方向从纵向变为横向时,viewpager 会破坏片段。

这是 ViewPagerAdapter.kt

internal class FragmentPagerAdapter(fm: FragmentManager, private val mNumbOfTabs: Int) : FragmentPagerAdapter(fm) {

    /**
     * return the fragment for each position
     */
    override fun getItem(position: Int): Fragment? {
        when (position) {
            SIGN_UP -> return SignUpFragment()
            LOGIN -> return LoginFragment()
            else -> return null
        }
    }

    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val ret = super.instantiateItem(container, position)
        return ret
    }

    /**
     * return number of tabs
     */
    override fun getCount(): Int {
        return mNumbOfTabs
    }

    companion object {
        private val SIGN_UP = 0
        private val LOGIN = 1
    }
}

以及我如何从 MainActivity 调用它的方式

Handler().postDelayed({
                fadeOutAndHideImage(imagelogo);
                tabs.addTab(tabs.newTab().setIcon(R.drawable.sign_in).setText(R.string.sign_up))
                tabs.addTab(tabs.newTab().setIcon(R.drawable.sign_in).setText(R.string.login))
                val adapter = FragmentPagerAdapter(supportFragmentManager, tabs.getTabCount())
                viewpager.setAdapter(adapter)
                viewpager.setOffscreenPageLimit(2)
                viewpager.addOnPageChangeListener(TabLayoutOnPageChangeListener(tabs))
                tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
                    override fun onTabSelected(tab: TabLayout.Tab) {
                        // Hide keyboard
                        (getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(viewpager.getWindowToken(), 0)
                        viewpager.setCurrentItem(tab.position)
                    }

                    override fun onTabUnselected(tab: TabLayout.Tab) {

                    }

                    override fun onTabReselected(tab: TabLayout.Tab) {

                    }
                })
            }, 5000)

屏幕在横向上运行良好,但是当我更改为纵向时......我认为图像会自己说话。一些类似的问题说明了有关保留片段的内容。

这是应用程序在bitbucket中的链接:https://Crdzbird@bitbucket.org/unidevelop/healthy-app.git

Fragment + ViewPager fail when orientation change

Android ViewPager orientation change

ViewPager fragments disappear when change screen rotation

但结果不同:(

[[编辑]]

SplashLayout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context="com.freelance.nicaragua_dev.healthyapp.UI.SplashActivity">

    <com.freelance.nicaragua_dev.healthyapp.Helper.Kenburns.KenBurnsView
        android:id="@+id/ken_burns_images"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>

    <ImageView
        android:id="@+id/imagelogo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:src="@drawable/logo" />

    <com.freelance.nicaragua_dev.healthyapp.Helper.Kenburns.KenBurnsView
        android:id="@+id/welcome_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:alpha="0.0"
        android:text="@string/app_name"
        android:textColor="@color/material_petal"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="24dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal">
    </LinearLayout>

    <android.support.v7.widget.CardView
        android:id="@+id/cardViewPrincipal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="150dp"
        android:layout_marginLeft="16dp"
        android:layout_centerInParent="true"
        android:layout_marginRight="16dp"
        android:layout_marginTop="80dp"
        app:cardCornerRadius="7dp"
        app:cardElevation="22dp"
        android:background="@color/transparent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                app:tabGravity="fill"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/white"
                app:tabIndicatorHeight="4dp" />

            <android.support.v4.view.ViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1" />
        </LinearLayout>


    </android.support.v7.widget.CardView>

</RelativeLayout>

和 SignUp.xml

<FrameLayout 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:background="@color/transparent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".UI.SignUpFragment">

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:fillViewport="true"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <android.support.design.widget.TextInputEditText
                    android:id="@+id/et_email"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="20dp"
                    android:layout_marginRight="20dp"
                    android:cursorVisible="true"
                    android:gravity="center|left|bottom"
                    android:hint="@string/email"
                    android:inputType="textEmailAddress"
                    android:maxLength="50"
                    android:paddingBottom="10dp"
                    android:textColor="@color/md_black_1000"
                    android:textSize="18sp" />

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

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/password"
                app:passwordToggleEnabled="true">

                <android.support.design.widget.TextInputEditText
                    android:id="@+id/et_password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="20dp"
                    android:layout_marginRight="20dp"
                    android:layout_marginTop="30dp"
                    android:cursorVisible="true"
                    android:gravity="center|left|bottom"
                    android:inputType="textPassword"
                    android:maxLength="50"
                    android:paddingBottom="10dp"
                    android:textColor="@color/md_black_1000"
                    android:textSize="18sp" />

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

            <Button
                android:id="@+id/buttonLogin"
                android:text="@string/sign_up"
                android:layout_gravity="center"
                android:layout_margin="15dp"
                android:padding="10dp"
                android:layout_marginRight="5dp"
                android:layout_width="150dp"
                android:layout_height="50dp"
                android:background="@drawable/red_button"
                android:textColor="@color/md_red_600" />

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

</FrameLayout>

【问题讨论】:

  • 你是否对不同的方向使用不同的布局?
  • 不,两个方向的布局都是一样的
  • 也为 viewpager 发布 xml 布局
  • 我更新了问题

标签: android android-layout android-fragments


【解决方案1】:

问题在于您的 activity_splash.xml 布局。 cardViewPrincipal 的下边距为 150dp,上边距为 80dp。减少这些值,因为大多数屏幕没有足够的空间来实现如此高的利润率。第二个原因是您已将 viewpager 的权重设置为 1 而不是仅仅匹配其父级。 奖金(与您的问题完全无关) 您还应该用 FrameLayout 替换 RelativeLayout,因为它昂贵。您应该避免使用它,因为它会降低帧速率。

你的 xml 应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context="com.freelance.nicaragua_dev.healthyapp.UI.SplashActivity">

    <com.freelance.nicaragua_dev.healthyapp.Helper.Kenburns.KenBurnsView
        android:id="@+id/ken_burns_images"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>

    <ImageView
        android:id="@+id/imagelogo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|center"
        android:layout_marginTop="10dp"
        android:src="@drawable/logo" />

    <com.freelance.nicaragua_dev.healthyapp.Helper.Kenburns.KenBurnsView
        android:id="@+id/welcome_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:alpha="0.0"
        android:text="@string/app_name"
        android:textColor="@color/material_petal"
        android:layout_gravity="bottom|center"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
       android:layout_gravity="bottom|center"
        android:layout_marginBottom="24dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <!--<Button-->
            <!--android:id="@+id/buttonSignup"-->
            <!--android:text="@string/sign_up"-->
            <!--android:layout_marginLeft="5dp"-->
            <!--android:layout_width="150dp"-->
            <!--android:layout_height="50dp"-->
            <!--android:background="@drawable/red_button"-->
            <!--android:textColor="@android:color/white" />-->
    </LinearLayout>

    <android.support.v7.widget.CardView
        android:id="@+id/cardViewPrincipal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="32dp"
        android:layout_gravity="top"
        app:cardCornerRadius="7dp"
        app:cardElevation="22dp"
        android:background="@color/transparent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                app:tabGravity="fill"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/white"
                app:tabIndicatorHeight="4dp" />

            <android.support.v4.view.ViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>


    </android.support.v7.widget.CardView>

</FrameLayout>

【讨论】:

  • 谢谢!现在一切都很完美:) 你先生是一个活生生的救星! :D
  • 很高兴为您提供帮助:)
【解决方案2】:

由于纵向模式和横向模式使用相同的布局,您可以编辑您的AndroidManifest.xml,并将此行添加到您不想重绘的Activity:

android:configChanges="keyboardHidden|orientation"

https://developer.android.com/guide/topics/resources/runtime-changes.html

现在,当这些配置之一发生变化时,MyActivity 不会 重新开始。相反,MyActivity 收到一个调用 onConfigurationChanged()。

也许这就是您在这种情况下要寻找的。​​p>

或者,您可以清除传递给onCreate() 的Bundle,因为该对象可能包含ViewPager 可能以不良方式使用的一些数据。

【讨论】:

  • 我已经按照你的建议确定了方向,但是,viewpager 总是不断改变我的片段:(
  • 如果你把Bundle设为null,比如:super.onCreate(null)怎么办?在你的Activity?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多