在自定义组件的属性集中访问 attrs
我有一个包含两个 TextView 的自定义组件,它们具有自定义大小设置方法(两个文本视图的比例约为 1:2)。由于这是相对布局的子类,因此它没有textSize属性,但我想知道是否仍然可以在XML实例化中为此组件设置该属性,然后从属性集中获取该属性以用于构造函数中的自定义方法。android:textSize
textSize
setSize()
我已经看到了使用自定义属性执行此操作的技术,但是如果我想获取已经在Android词典中的属性怎么办?
我有一个包含两个 TextView 的自定义组件,它们具有自定义大小设置方法(两个文本视图的比例约为 1:2)。由于这是相对布局的子类,因此它没有textSize属性,但我想知道是否仍然可以在XML实例化中为此组件设置该属性,然后从属性集中获取该属性以用于构造函数中的自定义方法。android:textSize
textSize
setSize()
我已经看到了使用自定义属性执行此操作的技术,但是如果我想获取已经在Android词典中的属性怎么办?
是的,这是可能的;
让我们假设您的相对布局声明(在 xml 中)具有用 14sp 定义的 textSize:
android:textSize="14sp"
在自定义视图的构造函数(采用 AttributeSet 的构造函数)中,您可以从 Android 的命名空间中检索属性,如下所示:
String xmlProvidedSize = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "textSize");
xmlProvidedSize 的值将类似于“14.0sp”,也许只需进行一点字符串编辑,您就可以提取数字。
声明自己的属性集的另一个选项会有点冗长,但它也是可能的。
因此,您有自定义视图,并且您的 TextViews 声明了如下内容:
public class MyCustomView extends RelativeLayout{
private TextView myTextView1;
private TextView myTextView2;
// rest of your class here
伟大。。。
现在,您还需要确保您的自定义视图覆盖了采用属性集的构造函数,如下所示:
public MyCustomView(Context context, AttributeSet attrs){
super(context, attrs);
init(attrs, context); //nice, clean method to instantiate your TextViews//
}
好的,现在让我们看看init()方法:
private void init(AttributeSet attrs, Context context){
// do your other View related stuff here //
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyCustomView);
int xmlProvidedText1Size = a.int(R.styleable.MyCustomView_text1Size);
int xmlProvidedText2Size = a.int(R.styleable.MyCustomView_text2Size);
myTextView1.setTextSize(xmlProvidedText1Size);
myTextView2.setTextSize(xmlProvidedText2Size);
// and other stuff here //
}
你可能想知道R.styleable.MyCustomView,R.styleable.MyCustomView_text1Size和R.styleable.MyCustomView_text2Size来自哪里;请允许我详细阐述这些。
您必须在attrs.xml文件(在 values 目录下)中声明属性名称,以便无论何时何地使用自定义视图,从这些属性收集的值都将在构造函数中传递。
因此,让我们看看您如何像您所问的那样声明这些自定义属性:这是我的全部吸引力.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
<attr name="text1Size" format="integer"/>
<attr name="text2Size" format="integer"/>
</declare-styleable>
</resources>
现在,您可以在 XML 中设置 TextViews 的大小,但如果不在布局中声明命名空间,则无需执行以下操作:
<com.my.app.package.MyCustomView
xmlns:josh="http://schemas.android.com/apk/res-auto"
android:id="@+id/my_custom_view_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
josh:text1Size="15"
josh:text2Size="30"
/>
请注意,我如何将命名空间声明为“josh”作为 CustomView 属性集中的第一行。
我希望这对乔希有所帮助,
接受的答案有点长。这是一个精简版本,我希望很容易理解。要将属性(或任何使用 / 的特性)添加到自定义视图中,请执行以下步骤。textSize
dp
sp
创建(或添加以下部分)到attrs.xml。请注意维度
格式。
<resources>
<declare-styleable name="CustomView">
<attr name="textSize" format="dimension" />
</declare-styleable>
</resources>
请注意自定义命名空间。app
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.myproject.CustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:textSize="20sp" />
</RelativeLayout>
请注意 ..在自定义视图中,只需处理像素。如果您需要转换为其他维度,请参阅此答案。getDimensionPixelSize
public class CustomView extends View {
private float mTextSize; // pixels
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.CustomView, 0, 0);
try {
mTextSize = a.getDimensionPixelSize(R.styleable.CustomView_textSize, 0);
} finally {
a.recycle();
}
}
/**
* @param size in SP units
*/
public void setTextSize(int size) {
mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
size, getResources().getDisplayMetrics());
mTextPaint.setTextSize(mTextSize);
invalidate();
requestLayout();
}
// ...
}