为 Android 视图设置全局样式

140

假设我希望我的应用程序中所有的TextView实例都具有textColor="#ffffff",是否有一种方法可以在一个地方设置它,而不是为每个TextView单独设置?


1
我已经更新了我的问题,以便它更加完整。 - Cristian
我正在这里做类似的事情!!! https://dev59.com/BWQn5IYBdhLWcg3wGD5s - Etienne Lawlor
4个回答

284
实际上,您可以为TextView(和大多数其他内置小部件)设置默认样式,而不需要进行自定义java类或单独设置样式。如果您查看Android源代码中的themes.xml,您将看到各种小部件的默认样式的一堆属性。关键是textViewStyle(或editTextStyle等)属性,您可以在自定义主题中覆盖它们。您可以按以下方式覆盖这些内容:创建一个styles.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme">
    <item name="android:textViewStyle">@style/MyTextViewStyle</item>
</style>

<style name="MyTextViewStyle" parent="android:Widget.TextView">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
</style>
</resources>

然后只需在AndroidManifest.xml中将该主题应用于您的应用程序:

<application […] android:theme="@style/MyTheme">…

你的所有文本视图都将默认使用MyTextViewStyle中定义的样式(在此示例中为粗体和红色)!

这已在API级别4及以上的设备上进行了测试,看起来效果非常好。


1
到目前为止,我看到的最优雅的解决方案。 - Italo Borssatto
@Steve,如果我在样式MyTheme中包含<item name="android:textViewStyle">@style/MyTextViewStyle</item>,然后将该样式应用于我的应用程序,所有的TextView都将按照该样式显示(甚至是操作栏中应用程序的名称)。如何解决操作栏的问题?我希望它具有默认外观。Github - Maksim Dmitriev
@Steve,如何在应用程序中同时应用操作栏和小部件主题? - Pratik Butani
我不确定如何区分ActionBar和其他内容。您可以找到设置ActionBar样式的位置,然后在那里添加<item name="android:textViewStyle">@style/MyTextViewStyle</item>,指向ActionBar默认样式(或类似的东西)。 - Steve Pomeroy
如果我已经在我的application标签中为另一个小部件定义了样式,那该怎么办? style属性似乎不接受多个值。 - jack_the_beast
显示剩余3条评论

54

有两种方法可以实现:

1. 使用样式

您可以通过在res/values目录中创建XML文件来定义自己的样式。假设您想要红色和粗体文本,则可以创建一个包含以下内容的文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyRedTheme" parent="android:Theme.Light">
    <item name="android:textAppearance">@style/MyRedTextAppearance</item>
  </style>
  <style name="MyRedTextAppearance" parent="@android:style/TextAppearance">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
  </style>
</resources>

你可以任意命名,比如res/values/red.xml。然后,在你想要使用该视图的部件中使用它即可,例如:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    style="@style/MyRedTheme"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

为了更深入的了解,您可以阅读这篇文章:理解Android主题和样式

2. 使用自定义类

这是另一种可能的方法,就是提供自己的TextView,始终将文本颜色设置为您想要的颜色;例如:

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.TextView;
public class RedTextView extends TextView{
    public RedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTextColor(Color.RED);
    }
}

接下来,您只需将其视为普通的TextView在您的XML文件中:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<org.example.RedTextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

你使用哪种方法取决于你的需求。如果你只想修改外观,那么最好的方法是第一种。另一方面,如果你想改变外观并为小部件添加一些新功能,则第二种方法是正确的选择。


使用自定义类应该是首选,因为这是更清晰的方法,并有助于保持 XML 文件的轻量级。 - Amit Kumar
1
@AmitKumar 不应该这样做!在这种情况下,这意味着为每个不同的属性值使用单独的自定义类。这会产生大量的膨胀代码,并使实际布局不再可读(您将不得不访问每个类以查看它正在做什么,而不是只读取几行xml)。只有在修改行为时才应使用自定义类,而不是仅更改视图的外观。 - Andre
无法从xml设置自定义视图的样式吗?为什么不能在用于填充自定义类的“custom_view_layout.xml”文件中使用它? - lucidbrot

5

要设置TextView中的默认文本颜色,请在您的主题中将android:textColorTertiary设置为所需的颜色:

<item name="android:textColorTertiary">@color/your_text_color</item>

许多其他Android控件的颜色可以使用框架属性进行控制,如果您使用支持库,则可以使用支持库属性进行控制。
要查看可以设置的属性列表,请查看styles.xmlthemes.xmlAndroid源代码,或者通过Dan Lew的这个非常有用的gist,尝试更改每个值并查看它们在屏幕上的变化。

谢谢,伙计!我花了很多时间弄清楚为什么textColorPrimary不起作用。 - pratt

3

定义一个样式并在每个小部件上使用它,定义一个主题来覆盖 Android 默认的小部件样式,或者定义一个字符串资源并在每个小部件中引用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接