【问题标题】:Android Selector Drawable doesnt work with attributesAndroid Selector Drawable 不适用于属性
【发布时间】:2015-06-10 12:43:49
【问题描述】:

我正在使用 attr 为我的项目创建一个可绘制的选择器,这样一旦我更改了主题颜色,我就不必对可绘制文件进行任何更改。我正在使用以下库:

compile 'com.android.support:appcompat-v7:+'
compile 'com.android.support:cardview-v7:+'
compile 'com.android.support:design:22.2.0'

这里是drawable的源代码:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="?attr/colorPrimary" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="?attr/colorPrimaryDark" android:state_pressed="true"/>
    <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
    <item android:drawable="?attr/colorPrimary"/>
</selector>

在同样的代码中,如果我用 colors.xml 文件中定义的颜色替换属性,同样的 drawable 可以工作。

带有颜色的可绘制示例:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/color_primary" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="@color/color_primary_dark" android:state_pressed="true"/>
    <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
    <item android:drawable="@color/color_primary"/>
</selector>

提前致谢!

【问题讨论】:

  • drawable 如何使用颜色???你必须通过 drawable 而不是 color
  • android 自行处理该部分。请参阅第二个可绘制对象的代码。有用。问题是当你使用属性时。
  • 我猜你必须使用类似this

标签: android drawable selector-drawable


【解决方案1】:

终于找到了问题所在。 android [pre-lollipop] 操作系统中有一个错误,它不允许您在 drawable 中使用 attr。这是错误的链接:

https://code.google.com/p/android/issues/detail?id=26251

Android 开发团队已发布修复,但它适用于 android L 及以上版本。有关此问题的解决方法,请参阅以下解决方案:

How to reference style attributes from a drawable?

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,截至 2019 年,该问题尚未解决,因此您不能将选择器中引用的属性作为可绘制对象。我将分享我为这个问题得到的解决方案,因为我没有看到它在这里发布。我在 mudit 在他的回答中提到的 bug report 的最后一条评论中找到了它。

    解决方法基本上是创建一个可绘制资源,该资源将引用属性值。

    为了说明您的情况,解决方案将是:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="?attr/colorPrimary" android:state_enabled="true" android:state_window_focused="false"/>
        <item android:drawable="?attr/colorPrimaryDark" android:state_pressed="true"/>
        <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
        <item android:drawable="?attr/colorPrimary"/>
    </selector>
    

    您可以将 ?attr/* 替换为可绘制资源:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/colorPrimaryDrawable" android:state_enabled="true" android:state_window_focused="false"/>
        <item android:drawable="@drawable/colorPrimaryDarkDrawable" android:state_pressed="true"/>
        <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
        <item android:drawable="@drawable/colorPrimaryDrawable"/>
    </selector>
    

    drawable 将被定义为:

    drawable/colorPrimaryDrawable

    <shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
        <solid android:color="?attr/colorPrimary" />
    </shape>
    

    drawable/colorPrimaryDarkDrawable

    <shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
        <solid android:color="?attr/colorPrimaryDark" />
    </shape>
    

    希望对你有帮助!!

    【讨论】:

      【解决方案3】:

      我不知道它是否仍然与您相关,但我一直在为同样的事情苦苦挣扎,我想我找到了一种解决方法(有点)。直接使用 ?attr/ 不起作用(适用于 api 21 及更高版本,但即便如此它也不能与颜色选择器一起使用(仅适用于可绘制对象)。

      所以我这样做了(给你我自己的例子)。 在 attr.xml 中创建属性

      <attr name="nav_item_color_selector" format="reference|color"/>
      

      然后在您使用的所有主题中,像这样添加属性(例如,对于 Light Theme):

      <item name="nav_item_color_selector">@color/text_color_selector_light</item>
      

      或者对于深色主题(默认):

      <item name="nav_item_color_selector">@color/text_color_selector</item>
      

      现在我的 text_color_selector.xml(两者)看起来像这样:

      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:state_selected="true"
            android:color="@color/myAccentColor" />
      <item android:state_selected="false" 
            android:color = "@color/myTextPrimaryColor"/>
      <item android:color="@color/myTextPrimaryColor" />
      

      当我想使用它们时,例如在为我的自定义图像视图着色时,我使用:

          <com.yourdomain.yourpackage.NavDrawerIcon
          android:layout_width="24dp"
          android:layout_height="24dp"
          android:layout_gravity="center_vertical"
          android:src="@mipmap/ic_launcher"
          android:id="@+id/nav_item_icon"
          android:layout_margin="24dp"
          android:tint = "?attr/nav_item_color_selector"
          android:tintMode="src_atop"/>
      

      您也可以使用 TypedValue 以编程方式重新调用它,如下所示:

          TypedValue typedValue = new TypedValue();
          Resources.Theme theme = context.getTheme();
          theme.resolveAttribute(R.attr.nav_item_color_selector, typedValue, true);
          XmlResourceParser parser = viewGroup.getContext().getResources().getXml(typedValue.resourceId);
          try {
              ColorStateList sl = ColorStateList.createFromXml(viewGroup.getContext().getResources(), parser);
              viewHolder.textView.setTextColor(sl);
      
          } catch (Exception e) {  }
      

      我希望这会有所帮助:-)

      【讨论】:

      • 感谢您的帮助,但此解决方案对我来说不可行,因为它需要我为 java 代码中的每个控件设置背景。
      • 我明白了。我不知道您需要实现什么,但如果它是布局或视图的背景,则可以使用 ?attr 设置它,并引用您在 xml 中创建的属性。不一定在java中。即使它是在java中,关键是你只做一次。因为一旦你获得了你使用的每个主题的属性,它就会读取引用并动态设置选择器。
      • @daxgirl 你有没有一个例子 sn-p 使用 TypedValue 的 attr 值和 StateListDrawable 在 pre-Lollipop 上?
      【解决方案4】:

      我在可绘制选择器中使用颜色属性时遇到了类似的问题。

      我通过制作颜色选择器而不是可绘制选择器解决了这个问题。 基本上,创建一个新资源,资源类型为颜色,这将是您的颜色选择器。在这里,与可绘制选择器不同,您可以毫无问题地使用您的属性:

      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item android:color="?colorBackgroundDisabled" android:state_enabled="false" />
          <item android:color="?colorBackground" />
      </selector>
      

      ^我将其命名为 selector_background。

      然后你可以使用那个选择器:

      <TextView
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@color/selector_background"/>
      

      【讨论】:

        【解决方案5】:

        而不是放一个“?”改成“@”

        【讨论】:

        • 它不适用于@。您希望我更改的任何特定原因?到 @。通常 attr 通过 ?而不是 @ 符号。
        猜你喜欢
        • 1970-01-01
        • 2016-08-12
        • 2019-06-23
        • 2011-05-23
        • 1970-01-01
        • 2015-03-13
        • 2010-10-25
        • 2021-06-03
        • 2016-06-06
        相关资源
        最近更新 更多