【问题标题】:Adding multiple LayerList to API 19 Device causing inflating error将多个 LayerList 添加到 API 19 设备导致充气错误
【发布时间】:2020-03-15 08:34:18
【问题描述】:

我正在尝试创建一个具有两个背景的按钮,即我的自定义背景

android:background="@drawable/background_profile_edit_button" + ?attr/selectableItemBackground```

完整按钮:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/fragprofile_constraint"
    app:layout_constraintRight_toRightOf="parent"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="16dp"
    android:background="@drawable/background_profile_edit_button"
    android:paddingStart="32dp"
    android:paddingTop="6dp"
    android:paddingEnd="32dp"
    android:paddingBottom="6dp"
    android:text="Edit Profile"
    android:textColor="@color/colorBlackFont"
    android:textSize="12sp"
    android:textStyle="bold"/>

这可以通过android:foreground="?attr/selectableItemBackground" 轻松解决,但这需要 api 23 而我的最小值是 19。

我还尝试了另一种在可绘制对象中使用图层列表的方法:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:shape="rectangle">
            <solid android:color="@color/colorWhite" />

            <stroke
                android:width="1dp"
                android:color="@color/dividerColor" />
            <corners android:radius="3dp"/>
        </shape>
    </item>

    <item
        android:drawable="?attr/selectableItemBackground">
    </item>


</layer-list>

这个层列表在我的更高 API 设备上完美运行。但是它导致我的 API 19 设备崩溃...

android.view.InflateException: Binary XML file line #201: Error inflating class TextView

这个人也有同样的问题,也没有答案:

LayerList error API 19: tag requires a 'drawable' attribute or child tag defining a drawable

TLDR:_____________________________________________

在 API 19 设备上执行此操作

【问题讨论】:

    标签: android layer-list


    【解决方案1】:

    现在我只是使用RelativeLayout 作为按钮的包装器。如果有人有没有NestedLayout Hacky Solution 的解决方案,那就太好了。

    
    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <RelativeLayout
            android:id="@+id/fragprofile_edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/background_profile_edit_button">
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="?attr/selectableItemBackground"/>
        </RelativeLayout>
    
    </RelativeLayout>
    

    编辑:这个问题的一个问题是相对布局上的android:background="@drawable/background_profile_edit_button" 导致圆角半径不起作用......在低于 API 21 的设备上......

    https://stackoverflow.com/a/30692236/11110509

    【讨论】:

      【解决方案2】:

      Context.getDrawable(Theme)Resources.getDrawable(int,Theme) 均在 Android SDK 级别 21 中引入。之前可绘制资源不支持主题属性。只是没有Theme 可用于加载属性。

      Alex Lockwood 的博文 Styling Colors & Drawables w/ Theme Attributes 对此进行了更好的解释。

      【讨论】:

        【解决方案3】:

        您是否尝试过直接在图层列表中引用可绘制对象而不是引用样式属性(遵循@tynn 的回答)?它起作用了吗?或者有什么理由不适合你?

        如果层列表适用于除 19 之外的所有 API,我可以建议一种解决方法/妥协。将当前图层列表保留在 drawable 文件夹和 drawable-v21 中(您可能需要创建此文件夹),然后创建适用于 API19 的替代按钮设计并将其保存在 drawable-v19 中,也许是您的应用程序在 API19 中看起来不会那么好,但至少它仍然可以在所有设备上正常运行。

        这通过告诉 android 在遇到 API19 时应该使用不同的可绘制资源来工作,您可以阅读更多关于它的信息 here。 android 会自动从最接近其 API 的 dawable-vXX 文件夹中获取其资源,如果在该 drawable-vXX 文件夹中找不到资源,则恢复到 drawable 文件夹。

        还有一个article,我发现有人对此也很着迷。 显然你可以尝试用一个按钮替换你的 textview 并使用 AppTheme 实现涟漪效果

        <!-- styles.xml -->
        <style name="AppTheme.YellowButton">
            <item name="colorButtonNormal">@color/yellow</item>
        </style>
        
        <!-- layout.xml -->
        <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.YellowButton"
        android:text="Yellow Tint Button" />
        

        让我知道它是否有效

        【讨论】:

        • 是的,我试过直接引用drawable。在更高的 API 设备 28 上它可以工作。在我的 API 19 设备上,它只是在启动时完全崩溃。
        • 似乎有人已经问过同样的问题,并且其他人也已经给了我的答案 XD stackoverflow.com/a/35976895/10637400 显然在 api21 下没有解决方案,所以你可以尝试我的妥协
        • 如果我理解正确,您希望您的按钮在单击时改变颜色。也许您可以为 api19 编写一些 java 代码,或者简单地使用我的方法创建文件夹 drawable-v19 和 drawable-v21 并接受这样一个事实,即您仍然使用 api19 的一小部分用户将无法享受该动画跨度>
        【解决方案4】:

        您可以在代码中完成。试试下面的代码:

        // rect.xml file in drawables
        <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid android:color="@android:color/white" />
        
            <stroke
                android:width="1dp"
                android:color="@android:color/holo_green_light" />
            <corners android:radius="3dp" />
        </shape>
        
        
        fun getLayer(id: Int) = if (android.os.Build.VERSION.SDK_INT < 21) resources.getDrawable(id)
        else resources.getDrawable(id, theme)
        
        // Get first shape layer
        val layer1 = getLayer(R.drawable.rect)
        
        // Get second layer from  attributes
        val a = theme.obtainStyledAttributes(
            R.style.AppTheme,
            intArrayOf(android.R.attr.selectableItemBackground)
        )
        val attributeResourceId = a.getResourceId(0, 0)
        val layer2 = getLayer(attributeResourceId)
        
        // Create layer list
        val layers = LayerDrawable(arrayOf(layer1, layer2))
        
        button.background = layers
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-03-19
          • 1970-01-01
          • 1970-01-01
          • 2016-08-11
          • 1970-01-01
          • 2018-11-02
          • 1970-01-01
          相关资源
          最近更新 更多