【问题标题】:Android use HorizontalScrollView for landscape and ScrollView for portraitAndroid 使用 Horizo​​ntalScrollView 横向和 ScrollView 纵向
【发布时间】:2021-08-31 19:26:35
【问题描述】:

我想为横向和纵向屏幕使用不同的布局。在纵向中,我想使用水平滚动的 Horizo​​ntalScrollView。在横向我想使用 ScrollView 垂直滚动。

它们运行良好,除了当我将设备方向从纵向转到横向时,它会崩溃并抱怨无法将 Horizo​​ntalScrollView 转换为 ScrollView。

是否应该重新加载布局而不是强制转换组件?堆栈全部在 android 代码中,而不是我的代码中,所以我不知道如何处理它。请帮忙,谢谢!

这是 res/layout 中的布局文件:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <HorizontalScrollView
        android:id="@+id/hsv_tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#d0d0d0"
        android:visibility="visible"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#b0b0b0"
            android:orientation="horizontal"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@+id/tools_draw"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:layout_marginRight="3dp"
                android:text="@string/tools_draw"
                android:textSize="10sp"
                app:drawableTopCompat="@drawable/tools_new" />

这是 res/layout-land 中的布局:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:id="@+id/hsv_tools"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="#d0d0d0"
        android:visibility="visible"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#b0b0b0"
            android:orientation="vertical"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent">

当我旋转手机时发生崩溃,堆栈跟踪是:

java.lang.RuntimeException: Unable to start activity ComponentInfo: java.lang.ClassCastException: android.widget.HorizontalScrollView$SavedState cannot be cast to android.widget.ScrollView$SavedState
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2604)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2670)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4370)
    at android.app.ActivityThread.access$1200(ActivityThread.java:178)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1523)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:207)
    at android.app.ActivityThread.main(ActivityThread.java:5845)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:768)
Caused by: java.lang.ClassCastException: android.widget.HorizontalScrollView$SavedState cannot be cast to android.widget.ScrollView$SavedState
    at android.widget.ScrollView.onRestoreInstanceState(ScrollView.java:1834)
    at android.view.View.dispatchRestoreInstanceState(View.java:14953)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3249)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3255)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3255)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3255)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3255)
    at android.view.View.restoreHierarchyState(View.java:14931)
    at com.android.internal.policy.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2068)
    at android.app.Activity.onRestoreInstanceState(Activity.java:1036)
    at android.app.Activity.performRestoreInstanceState(Activity.java:991)
    at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1170)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)

【问题讨论】:

  • 请分享您的代码和堆栈跟踪,以便我们提供帮助。
  • 我很困惑为什么您要尝试使用水平滚动视图进行垂直滚动,为什么不能只使用滚动视图进行垂直滚动?
  • 抱歉描述中的拼写错误。我的意思是在纵向屏幕中我希望 Horizo​​ntalScrollView 水平滚动,在横向屏幕中我希望 ScrollView 垂直滚动。

标签: android


【解决方案1】:

只是基于迈克尔的回答的一些进一步发现。

所以当我有不同的纵向和横向布局时,所有命名的视图在纵向和横向布局中必须是相同的类型,否则当用户旋转屏幕时它会崩溃。对于未命名的视图,这不是必需的。

对于我的问题,我创建了 Horizo​​ntalScrollView 和 ScrollView 并在 id 中添加了后缀 _hsv 和 _sv。对于纵向不使用 _sv,因此将可见性设置为 Gone,对于横向设置 _hsv 可见性为 Gone。

在代码中,我通过检查可见性 == View.Gone 来检查哪个正在使用。这解决了我所有的问题。

谢谢迈克尔和大家!

【讨论】:

    【解决方案2】:

    与您的想法相反,HorizontalScrollView 不继承自 ScrollView。

    它们都有 SavedState 内部类,但它们是不同的。

    当您将方向从纵向更改为横向或反之亦然时,这会导致 ID 为 hsv_tools 的滚动视图使用其 SavedState 保存其实例状态。

    然后,当 Activity/Fragment 被重新创建并且您的布局被膨胀并且状态被恢复时,并且由于您对 ScrollView 和 HoriztonalScrollView 使用相同的 id,放置在 Bundle 中的 SavedState 将用于滚动方向改变前的视图。

    这就是导致 ClassCastException 的原因。

    我建议,由于您有一个完全不同类型的滚动视图,具体取决于纵向或横向模式,您为每个视图提供不同的 id,然后通过首先检查布局中视图的存在来在代码中处理这个问题,如果它在那里,你就知道你正在处理的是哪一个。

    【讨论】:

      【解决方案3】:

      如果不查看 RUN 日志和代码,我认为任何人都无法帮助您,您能否将两者都复制到您的问题中?

      抱歉没有足够的代表发表评论。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        相关资源
        最近更新 更多