以编程方式设置 TextView 的样式
Posted
技术标签:
【中文标题】以编程方式设置 TextView 的样式【英文标题】:Set style for TextView programmatically 【发布时间】:2011-03-09 16:42:30 【问题描述】:我正在尝试使用具有如下样式的 TextView
构造函数:
TextView myText = new TextView(MyActivity.this, null, R.style.my_style);
但是,当我这样做时,文本视图似乎没有采用该样式(我通过将其设置在静态对象上来验证该样式)。
我也尝试过使用myText.setTextAppearance(MyActivity.this, R.style.my_style)
,但它也不起作用。
【问题讨论】:
【参考方案1】:我不相信您可以以编程方式设置样式。为了解决这个问题,您可以创建一个指定样式的模板布局 xml 文件,例如在 res/layout create tvtemplate.xml 中,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:text="This is a template"
style="@style/my_style" />
然后将其膨胀以实例化您的新 TextView:
TextView myText = (TextView)getLayoutInflater().inflate(R.layout.tvtemplate, null);
【讨论】:
这胜过 Dandre Allison 的回答是它不需要 API v11。 它可能有效,但这没有意义。怎么可能用 xml 文件来设置呢?如果不是以编程方式。不使用 xml 文件是有原因的,其中一个原因是我习惯于编写代码来构建 UI,所以我不想学习一种新的方法,因为我的内存有限,我想保留一些空间其他事情。 @IharobAlAsimi 没错,所有事情都可以通过编程方式完成,而且 LayoutInflater 知道将 XML 转换为对象的一切。可悲的是,很多这样的东西都隐藏在私有 API 下,创建一些对象的唯一方法是向构造函数提供 AttributeSet。 与所有其他答案不同,这实际上适用于微调器,因此对您来说是一颗金星 只有此解决方案适用于我的样式中定义的所有属性,这与具有 4 参数构造函数的解决方案不同(例如,textAppearance 定义为样式)。【参考方案2】:您可以创建一个通用样式并在多个文本视图上重复使用它,如下所示:
textView.setTextAppearance(this, R.style.MyTextStyle);
编辑:this指上下文
【讨论】:
只要您所做的一切都是在模仿文本的“风格”,您的答案就有效。如果您尝试对 TextView 执行其他操作,例如添加填充或边距,则它不起作用。所以,我不是说你错了,但你的答案是有限的。在运行时膨胀视图是应用综合样式的唯一方法。 使用膨胀模板和使用setTextAppearance这两种方案都是合理的。要解决第二种解决方案的填充/边距问题,您可以调用 textView.setLayoutParams(layoutParams) 此方法在 API 级别 23 中已弃用。在 API 23+ 中使用 setTextAppearance(int) 代替。 确保版本至少为 API 23 (M) 使用支持库中的方法,TextViewCompat.setTextAppearance
【参考方案3】:
您可以像这样将ContextThemeWrapper 传递给构造函数:
TextView myText = new TextView(new ContextThemeWrapper(MyActivity.this, R.style.my_style));
【讨论】:
好东西!在支持 API 8 的同时以编程方式设置样式的唯一方法。 出于某种原因,它不会影响我按钮的样式。我已将我的风格定义为:<style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>
。然后我用一个构造来调用它:new Button(new ContextThemeWrapper(context, R.style.TabButton));
。但是该按钮只是忽略了我的设置。我在这里做错了吗?
@AlaksiejN.You 应该像这样继承 Widget.Button 样式parent="@android:style/Widget.Button"
@maxcanna 出于某种原因添加parent
并没有改变一点。所以我只是继续使用inflate
解决方案。
@AliakseiN。您需要使用 3-arg 构造函数,例如new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0)
。否则,将应用默认按钮样式,并且此样式将覆盖您通过 ContextThemeWrapper 合并到主题中的按钮样式。【参考方案4】:
您可以在构造函数中设置样式(但样式不能动态更改/设置)。
View(Context, AttributeSet, int)
(int
是当前主题中包含对样式的引用的属性)
Answer from Romain Guy
reference
【讨论】:
您的回答具有误导性 - 您是否尝试将本主题阅读到最后? 如何误导?接受的答案具有误导性,因为 Romain Guy 明确表示您可以以编程方式“设置”样式。只是没有工具可以动态更改它。不过,这个帖子似乎并不认为是这种情况。 注意,此调用需要 API 级别 11。 @PaulVerest 这不是报价单。 最后一个 int 不是样式资源。它是“当前主题中的一个属性,包含对为视图提供默认值的样式资源的引用。”【参考方案5】:参数 int defStyleAttr
没有指定样式。来自 Android 文档:
defStyleAttr - 当前主题中包含 对样式资源的引用,该资源为 看法。可以为 0 以不查找默认值。
要在 View 构造函数中设置样式,我们有两种可能的解决方案:
使用 ContextThemeWrapper:
ContextThemeWrapper wrappedContext = new ContextThemeWrapper(yourContext, R.style.your_style);
TextView textView = new TextView(wrappedContext, null, 0);
使用四参数构造函数(从 LOLLIPOP 开始可用):
TextView textView = new TextView(yourContext, null, 0, R.style.your_style);
关键 - defStyleAttr
参数应为 0 以将我们的样式应用于视图。
【讨论】:
感谢您的回答。我可以确认这对我有用。特别感谢您在回答末尾的注释。 样式不知何故不适用于边距属性。为什么?【参考方案6】:(目前)不支持动态更改样式。您必须通过 XML 在创建视图之前设置样式。
【讨论】:
其实是一样的 @njzk2 谢谢...显然在发布之前没有考虑他的评论。在构建 UI 之前无法以编程方式设置样式,因此将使用相同的代码以编程方式更改或设置样式。【参考方案7】:接受的答案对我来说是很好的解决方案。唯一要补充的是inflate()
方法。
在接受的答案中,所有android:layout_*
参数都不会被应用。
原因是无法调整,因为null
被传递为ViewGroup parent
。
你可以这样使用它:
View view = inflater.inflate(R.layout.view, parent, false);
而parent
是ViewGroup
,您可以从中调整android:layout_*
。
在这种情况下,将设置所有相关属性。
希望它对某人有用。
【讨论】:
【参考方案8】:当使用可能使用样式继承(或事件样式属性)的自定义视图时,您必须修改第二个构造函数以免丢失样式。这对我有用,无需使用 setTextAppearence():
public CustomView(Context context, AttributeSet attrs)
this(context, attrs, attrs.getStyleAttribute());
【讨论】:
【参考方案9】:我也遇到了这个问题,我找到了以编程方式设置样式的方法。也许你们都需要它,所以我在那里更新。
View 构造函数的第三个参数在你的主题中接受一种 attr 作为源代码:
public TextView(Context context, AttributeSet attrs)
this(context, attrs, com.android.internal.R.attr.textViewStyle);
所以你必须传递一种类型的 R.attr.** 而不是 R.style.**
在我的代码中,我执行了以下步骤:
首先,在 attr.xml 中自定义一个供主题使用的自定义 attr。
<attr name="radio_button_style" format="reference" />
其次,在 style.xml 中指定您使用的主题中的样式。
<style name="AppTheme" parent="android:Theme.Translucent">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<item name="radio_button_style">@style/radioButtonStyle</item>
</style>
<style name="radioButtonStyle" parent="@android:style/Widget.CompoundButton.RadioButton">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">64dp</item>
<item name="android:background">#000</item>
<item name="android:button">@null</item>
<item name="android:gravity">center</item>
<item name="android:saveEnabled">false</item>
<item name="android:textColor">@drawable/option_text_color</item>
<item name="android:textSize">9sp</item>
</style>
最后,使用它!
RadioButton radioButton = new RadioButton(mContext, null, R.attr.radio_button_style);
以编程方式创建的视图将在您的主题中使用指定的样式。
你可以试一试,希望它能完美地为你工作。
【讨论】:
【参考方案10】:我们可以使用TextViewCompact.setTextAppearance(textView, R.style.xyz)
。
Android doc 供参考。
【讨论】:
【参考方案11】:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
textView.setTextAppearance(R.style.yourStyle)
【讨论】:
【参考方案12】:我只测试了EditText,但是你可以使用方法
public void setBackgroundResource (int resid)
应用在 XML 文件中定义的样式。
这个方法属于 View 我相信它适用于任何 UI 元素。
问候。
【讨论】:
根据the documentation,这只适用于可绘制对象,而不适用于样式。因此,如果这真的有效,那只是“偶然”,你不应该依赖它。以上是关于以编程方式设置 TextView 的样式的主要内容,如果未能解决你的问题,请参考以下文章
Android - 以编程方式设置 TextView TextStyle?