【问题标题】:Android layout renders wrong on MarshmallowAndroid 布局在 Marshmallow 上呈现错误
【发布时间】:2016-01-07 15:04:35
【问题描述】:

我刚刚注意到我的 Android 应用程序布局在 Marshmallow 上显示时出现问题。在装有 Android 5.1.1 的 Nexus 5 上正常,但在装有最新版本 Android 的 Nexus 5 和 Nexus 5x 上呈现错误。

布局由与底部对齐的小三角形(见红色部分)组成,在其上方有一些视图(白色)应该跨越其父级(灰色部分)的所有可用高度。

这就是它在 Android 5.1.1 (Nexus 5) 上的呈现方式:

在 Android 6.0(Nexus 5 和 Nexus 5X)上是:

问题看起来像红色视图不尊重其父对齐方式(底部,右侧)并且它使白色视图(位于上方)消失。

灰色视图及其子视图的简化布局是(我添加了一些背景颜色来查看视图边界):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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"    
    android:background="#777777">

    <View 
        android:id="@+id/preview_triangle"
        android:layout_width="@dimen/preview_triangle_width"
        android:layout_height="@dimen/preview_triangle_height"
        android:layout_marginRight="@dimen/preview_triangle_margin_right"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:background="#ff0000"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/preview_triangle"   
        android:orientation="horizontal">
        <View
            android:layout_width="@dimen/preview_margin_horizontal"
            android:layout_height="match_parent"/>
        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:padding="3dp"
            android:background="@drawable/round_rectangle_white_radius_3dp">
            <WebView
                android:id="@+id/preview_webview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </FrameLayout>

        <FrameLayout
            android:id="@+id/preview_close"
            android:layout_width="@dimen/preview_margin_horizontal"
            android:layout_height="@dimen/preview_margin_horizontal">
            <ImageView          
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="left|top"
                android:layout_marginLeft="@dimen/preview_close_margin_left"
                android:src="@drawable/icn_close"
                android:contentDescription="@null"/>    
        </FrameLayout>
    </LinearLayout>      
</RelativeLayout>

上面的布局被放入单独的 preview.xml 文件中,然后像这样包含在主布局中:

<include
        android:id="@+id/fragment_main_loyalty_preview_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_below="@id/fragment_main_loyalty_logo_container"
        android:layout_above="@id/fragment_main_loyalty_buttons_container"
        android:layout_marginTop="@dimen/fragment_main_loyalty_preview_container_margin_top"
        android:layout_marginBottom="@dimen/fragment_main_loyalty_preview_container_margin_bottom"      
        android:visibility="visible"
        layout="@layout/preview"/>

更新

如果我用 FrameLayout 左右替换托管 ScrollView,问题就会消失。

我真的不明白为什么中间父级渲染得很好,而它的子级会受到最顶层父级的影响:)

只需在设计器中切换目标API,就可以在Eclipse内部重现这种情况。

更新 - 简化测试用例

下面是我能够创建和重现我的问题的最简单的布局。 基本上,红色区域应位于绿色和蓝色区域之间。 红色区域的高度应与绿色和蓝色视图之间的可用空间相匹配,因为存在另一个视图(请参阅@id/margin_placeholder),该高度会影响这两个视图之间的距离。

在红色区域内,我想将白色视图放在红色区域的底部。 而这个小白汉在Android 6.0上的渲染方式不一样:

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <FrameLayout
            android:id="@+id/top"
            android:layout_width="match_parent"
            android:layout_height="90dp"
            android:layout_marginTop="10dp"
            android:background="#007700"/>

        <View
            android:id="@+id/margin_placeholder"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_below="@id/top"/>

        <FrameLayout
            android:id="@+id/bottom"
            android:layout_width="match_parent"
            android:layout_height="90dp"
            android:layout_below="@id/margin_placeholder"
            android:background="#000077"/>

        <RelativeLayout
            android:id="@+id/middle"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_below="@id/top"
            android:layout_above="@id/bottom"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:background="#770000">
            <View
                android:layout_width="16dp"
                android:layout_height="8dp"
                android:layout_marginRight="16dp"
                android:layout_alignParentBottom="true"
                android:layout_alignParentRight="true"
                android:background="#ffffff"/>
        </RelativeLayout>       
    </RelativeLayout>
</ScrollView>

【问题讨论】:

  • 如果高度为 0dp,你的 布局不应该有权重吗?
  • 我忘了说,但是你可以看到layout_above,include标签的父布局是RelativeLayout。无论如何,preview.xml 中包含的“灰色”视图渲染得很好。是红色的,在 preview.xml 中放置不正确。

标签: android android-layout android-6.0-marshmallow


【解决方案1】:

如果我将 targetSdkVersion 从 16 升级到 20,效果会很好。

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2017-09-20
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多