【问题标题】:Overriding referenced style attributes覆盖引用的样式属性
【发布时间】:2013-06-10 19:57:47
【问题描述】:

阅读References To Theme Attributes 后,我试图在我设置的自定义主题中引用属性的值。

我正在将用户定义的样式应用于CheckedTextView

<CheckedTextView
    android:id="@+id/contactInfo"
    style="@style/ListViewCheckedTextViewRowStyle" >
</CheckedTextView>

用户自定义样式定义为:

<style name="ListViewCheckedTextViewRowStyle" parent="@style/ListViewRowStyle">
    <item name="android:checkMark">?android:listChoiceIndicatorMultiple</item>
</style>

我创建的主题定义为:

<style name="Theme.Yellowgreen" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:listChoiceIndicatorMultiple">@drawable/btn_check_holo_light</item>
</style>

但是,显示的 checkMark 样式是设备的默认主题的可绘制对象,而不是我的用户定义的可绘制对象。

我可以让我的drawable显示的唯一方法是:

<style name="ListViewCheckedTextViewRowStyle" parent="@style/ListViewRowStyle">
    <item name="android:checkMark">@drawable/btn_check_holo_light</item>
</style>

但这违背了覆盖此属性的全部目的,特别是因为我想在多个主题中覆盖此属性。

我在ActivityonCreate() 方法中设置主题,如下所示:

public void onCreate(Bundle savedInstanceState) {
    this.setTheme(R.style.Theme_Yellowgreen);
    super.onCreate(savedInstanceState);
    // ...
}

我还尝试在 AndroidManifest.xml 文件中设置主题,例如:

<application android:theme="@style/Theme.Yellowgreen" >

但这没有用。可能出了什么问题?

更新

我刚刚创建了一个小示例项目,看起来我上面发布的代码正在运行。所以我必须有一些其他样式覆盖这个属性,或者它可能与我的布局 xml 文件有关。

在我的大型项目中,Activity 中有两个 Fragments。两个Fragments 都有ListviewsAdapters 支持。在Fragment AAdaptergetView()方法如下:

public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.contact_entry, null);
    }

    //...

    return convertView;
}

Fragment BAdaptergetView()方法如下:

public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item, parent, false);
    }

    //...

    return convertView;
}

布局定义如下:

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    
    <include layout="@layout/list_item_header" />
    
    <include layout="@layout/contact_entry" />

    <View android:id="@+id/list_divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@android:drawable/divider_horizontal_dark" />

</LinearLayout>

list_item_header.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/header_text"
    android:layout_width="match_parent"
    android:layout_height="25dip"
    android:background="@color/dark_blue"
    android:gravity="center_vertical"
    android:paddingLeft="6dip"
    android:textColor="@color/white"
    android:textSize="14sp"
    android:textStyle="bold" />

contact_entry.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/contactEntry"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:orientation="horizontal" >

    <QuickContactBadge
        android:id="@+id/contactPic"
        style="@style/ContactPicStyle" />

    <CheckedTextView
        android:id="@+id/contactInfo"
        style="@style/ListViewCheckedTextViewRowStyle" >
    </CheckedTextView>

</LinearLayout>

由于某种原因,Fragment B 中的主题 checkMark 属性未正确呈现,而在 Fragment A 中,checkMark 使用当前的 YellowGreen 主题并且样式正确。为什么会发生这种情况?

【问题讨论】:

  • 您是否在清单中指定了 YellowGreen 主题?
  • 我刚刚创建了一个示例项目来测试您的样式文件,并且一切正常。所以我第二个dominus'问题:你有没有在清单中将活动主题设置为YellowGreen
  • 嘿@dominus 和@Idolon,我更新了这个问题。我尝试以两种不同的方式设置活动主题,但未能成功覆盖 android:listChoiceIndicatorMultiple 样式属性。
  • 如果您的主题名称是YellowGreen,您为什么要放入清单@style/Theme.Yellowgreen。我对自定义主题了解不多,只是想弄清楚。
  • @GokhanArik,我更正了主题名称。这是原帖中的一个错字。

标签: android styles themes overriding checkedtextview


【解决方案1】:

我认为您的主题中需要该行

<item name="android:checkedTextViewStyle">@style/ListViewCheckedTextViewRowStyle</item>

所以它看起来像这样:

<style name="Theme.Yellowgreen" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:listChoiceIndicatorMultiple">@drawable/btn_check_holo_light</item>
    <item name="android:checkedTextViewStyle">@style/ListViewCheckedTextViewRowStyle</item>
</style>

更新

在问题更新和 cmets 中的一些附加信息后,我们发现问题出在Context。我在那个问题中犯了同样的错误:Android color selector doesn't work with custom attributes

一个片段被传递给Activity,另一个片段被传递给Application。我不是专家,但即使这两个类都在扩展Context,只有Activity 扩展了ContextThemeWrapper,其中包含有关样式的信息。阅读那篇文章可能有助于将来理解上下文:http://www.doubleencore.com/2013/06/context/

【讨论】:

  • 嘿@Mikoos,我刚刚尝试将此属性添加到我的主题中,但不幸的是它没有覆盖属性android:listChoiceIndicatorMultiple
  • 如果您在 github 上向我们提供带有 cmets 的整个示例项目,您究竟想要实现什么,这可能会更容易。可以使用轮询请求给出解决方案。
  • 感谢@Mikoos,我已经发布了更多我的项目代码,并相信我越来越接近找出问题所在。希望我已经提供了足够的细节。
  • mInflater 的上下文是什么?如果您使用 context.getApplicationContext() 将上下文传递给适配器,它将无法正确设置样式。您需要传递活动上下文。
  • 谢谢@Mikoos。我无意中将 context.getApplicationContext() 传递给了Fragment B,我修复了这个问题,最终样式设置正确。您能否更新您的答案并说明为什么必须通过 Activity Context 而不是 Application Context,我会接受您的答案并奖励您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 2011-05-13
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
相关资源
最近更新 更多