为什么在通过自定义视图属性传递样式时文本不是粗体?
Why text is not bold when passing the style through custom view attributes?
假设我有 .xml
风格:
<style name="MaterialPreviewDetailsTextSmall">
<item name="android:layout_marginLeft">@dimen/material_margin</item>
<item name="android:textColor">@color/material_preview_backgroud</item>
<item name="android:textSize">@dimen/material_normal_smal_text</item>
<item name="android:textStyle">bold</item>
</style>
我想通过属性将其传递给自定义视图:
<pl.valueadd.ledoc.view.ViewPreviewRow
...
app:view_title="@string/equipment_overview_id_label"
app:view_title_style="@style/MaterialPreviewDetailsTextSmall"/>
在自定义视图中,我获取样式属性并将其应用于 TextView
:
public class ViewPreviewRow extends RelativeLayout {
TextView tvTitle;
public ViewPreviewRow(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
initView(context);
obtainStyledAttributes(context, attrs);
}
private void obtainStyledAttributes(Context context, AttributeSet attrs) {
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.ViewPreviewRow);
CharSequence text = attributes.getString(R.styleable.ViewPreviewRow_view_title);
if (text != null) {
tvTitle.setText(text);
} else {
throw new NullPointerException("Attribute view_title cannot be null");
}
int appearance = attributes.getResourceId(R.styleable.ViewPreviewRow_view_title_style, 0);
if (appearance != 0) {
setTextViewAppearance(tvTitle, appearance);
tvTitle.requestLayout();
}
...
attributes.recycle();
}
问题是:
Why the text has appropriate color, size, marginLeft however is not bold?
我找到了答案。
期待的样式属性可以一一应用:
int appearance = attributes.getResourceId(R.styleable.ViewPreviewRow_view_title_style, 0);
applyBold(context, attrs, appearance, tvTitle);
applyTextSize(context, attrs, appearance, tvTitle);
applyTextColor(context, attrs, appearance, tvTitle);
private void applyBold(Context context, AttributeSet attrs, int style, TextView textView) {
int[] textStyleAttr = new int[]{android.R.attr.textStyle};
int indexOfAttrTextStyle = 0;
TypedArray a = context.obtainStyledAttributes(style, textStyleAttr);
int styleIndex = a.getInt(indexOfAttrTextStyle, -1);
a.recycle();
setTypefaceFromAttrs(textView, styleIndex);
}
private void applyTextSize(Context context, AttributeSet attrs, int style, TextView textView) {
int[] textStyleAttr = new int[]{android.R.attr.textSize};
int indexOfAttrTextStyle = 0;
TypedArray a = context.obtainStyledAttributes(style, textStyleAttr);
int size = a.getDimensionPixelSize(indexOfAttrTextStyle, -1);
a.recycle();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
}
private void applyTextColor(Context context, AttributeSet attrs, int style, TextView textView) {
int[] textStyleAttr = new int[]{android.R.attr.textColor};
int indexOfAttrTextStyle = 0;
TypedArray a = context.obtainStyledAttributes(style, textStyleAttr);
ColorStateList color = a.getColorStateList(indexOfAttrTextStyle);
if (color == null) {
color = ColorStateList.valueOf(a.getColor(indexOfAttrTextStyle, -1));
}
a.recycle();
textView.setTextColor(color);
}
private void setTypefaceFromAttrs(TextView textView, int styleIndex) {
textView.setTypeface(Typeface.DEFAULT);
if (styleIndex == 1) {
textView.setTypeface(null, Typeface.BOLD);
} else {
textView.setTypeface(null, Typeface.NORMAL);
}
}
但是这个解决方案效率很低。它需要为每个预期属性初始化 TypedArray
(初始化它是一项非常耗费内存和时间的任务)。但是...它有效。
假设我有 .xml
风格:
<style name="MaterialPreviewDetailsTextSmall">
<item name="android:layout_marginLeft">@dimen/material_margin</item>
<item name="android:textColor">@color/material_preview_backgroud</item>
<item name="android:textSize">@dimen/material_normal_smal_text</item>
<item name="android:textStyle">bold</item>
</style>
我想通过属性将其传递给自定义视图:
<pl.valueadd.ledoc.view.ViewPreviewRow
...
app:view_title="@string/equipment_overview_id_label"
app:view_title_style="@style/MaterialPreviewDetailsTextSmall"/>
在自定义视图中,我获取样式属性并将其应用于 TextView
:
public class ViewPreviewRow extends RelativeLayout {
TextView tvTitle;
public ViewPreviewRow(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
initView(context);
obtainStyledAttributes(context, attrs);
}
private void obtainStyledAttributes(Context context, AttributeSet attrs) {
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.ViewPreviewRow);
CharSequence text = attributes.getString(R.styleable.ViewPreviewRow_view_title);
if (text != null) {
tvTitle.setText(text);
} else {
throw new NullPointerException("Attribute view_title cannot be null");
}
int appearance = attributes.getResourceId(R.styleable.ViewPreviewRow_view_title_style, 0);
if (appearance != 0) {
setTextViewAppearance(tvTitle, appearance);
tvTitle.requestLayout();
}
...
attributes.recycle();
}
问题是:
Why the text has appropriate color, size, marginLeft however is not bold?
我找到了答案。
期待的样式属性可以一一应用:
int appearance = attributes.getResourceId(R.styleable.ViewPreviewRow_view_title_style, 0);
applyBold(context, attrs, appearance, tvTitle);
applyTextSize(context, attrs, appearance, tvTitle);
applyTextColor(context, attrs, appearance, tvTitle);
private void applyBold(Context context, AttributeSet attrs, int style, TextView textView) {
int[] textStyleAttr = new int[]{android.R.attr.textStyle};
int indexOfAttrTextStyle = 0;
TypedArray a = context.obtainStyledAttributes(style, textStyleAttr);
int styleIndex = a.getInt(indexOfAttrTextStyle, -1);
a.recycle();
setTypefaceFromAttrs(textView, styleIndex);
}
private void applyTextSize(Context context, AttributeSet attrs, int style, TextView textView) {
int[] textStyleAttr = new int[]{android.R.attr.textSize};
int indexOfAttrTextStyle = 0;
TypedArray a = context.obtainStyledAttributes(style, textStyleAttr);
int size = a.getDimensionPixelSize(indexOfAttrTextStyle, -1);
a.recycle();
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
}
private void applyTextColor(Context context, AttributeSet attrs, int style, TextView textView) {
int[] textStyleAttr = new int[]{android.R.attr.textColor};
int indexOfAttrTextStyle = 0;
TypedArray a = context.obtainStyledAttributes(style, textStyleAttr);
ColorStateList color = a.getColorStateList(indexOfAttrTextStyle);
if (color == null) {
color = ColorStateList.valueOf(a.getColor(indexOfAttrTextStyle, -1));
}
a.recycle();
textView.setTextColor(color);
}
private void setTypefaceFromAttrs(TextView textView, int styleIndex) {
textView.setTypeface(Typeface.DEFAULT);
if (styleIndex == 1) {
textView.setTypeface(null, Typeface.BOLD);
} else {
textView.setTypeface(null, Typeface.NORMAL);
}
}
但是这个解决方案效率很低。它需要为每个预期属性初始化 TypedArray
(初始化它是一项非常耗费内存和时间的任务)。但是...它有效。