Android Marshmallow 上的布局呈现错误

Android layout renders wrong on Marshmallow

我刚刚注意到我的 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"/>

更新

如果我将托管 ScrollView 替换为 FrameLayout 等,问题就会消失。

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

只需在设计器中切换目标 API 即可在 Eclipse 中重现这种情况。

更新 - 简化的测试用例

下面是我能够创建和重现我的问题的最简单的布局。 基本上红色区域应该放在绿色和蓝色区域之间。 红色区域的高度应与绿色和蓝色视图之间可用的 space 匹配,因为还有另一个视图(请参阅@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>

如果我将 targetSdkVersion 从 16 升级到 20,它会呈现良好。