Java 访问自定义组件的AttributeSet中的属性
我有一个自定义组件,其中包含两个启用了自定义大小设置方法的文本视图(两个文本视图的比例约为1:2)。因为这是RelativeLayout的一个子类,所以它没有textSize属性,但我想知道是否仍然可以在该组件的XML实例化中设置Java 访问自定义组件的AttributeSet中的属性,java,android,textview,android-relativelayout,Java,Android,Textview,Android Relativelayout,我有一个自定义组件,其中包含两个启用了自定义大小设置方法的文本视图(两个文本视图的比例约为1:2)。因为这是RelativeLayout的一个子类,所以它没有textSize属性,但我想知道是否仍然可以在该组件的XML实例化中设置android:textSize属性,然后从属性集中抓取textSize属性以用于我的自定义setSize()构造函数中的方法 我已经见过使用自定义属性来实现这一点的技术,但是如果我想获取android词典中已经存在的属性,该怎么办?是的,这是可能的 让我们假设您的Re
android:textSize
属性,然后从属性集中抓取textSize
属性以用于我的自定义setSize()
构造函数中的方法
我已经见过使用自定义属性来实现这一点的技术,但是如果我想获取android词典中已经存在的属性,该怎么办?是的,这是可能的
让我们假设您的RelativeLayout声明(xml)使用14sp定义了textSize:
android:textSize="14sp"
在自定义视图(AttributeSet中的视图)的构造函数中,您可以从Android的命名空间中检索属性,如下所示:
String xmlProvidedSize = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "textSize");
xmlProvidedSize的值类似于“14.0sp”,也许只需编辑一点字符串,就可以提取数字
声明自己的属性集的另一个选项有点冗长,但也有可能 因此,您的自定义视图和文本视图声明如下:
public class MyCustomView extends RelativeLayout{
private TextView myTextView1;
private TextView myTextView2;
// rest of your class here
太好了
现在,您还需要确保自定义视图覆盖采用AttributeSet的构造函数,如下所示:
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目录下)中声明属性名称,以便在使用自定义视图时,从这些属性收集的值将被交给构造函数
那么,让我们看看如何按照您的要求声明这些自定义属性:
这是我的全部attrs.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中设置TextView的大小,但必须在布局中声明名称空间,以下是如何设置的:
<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属性集中的第一行的
我希望这对Josh有所帮助,公认的答案有点长。这是一个简明的版本,我希望很容易理解。要将
textSize
属性(或任何使用dp
/sp
的属性)添加到自定义视图,请执行以下步骤
1.创建自定义属性
创建(或添加以下部分)到attrs.xml。注意格式
3.在自定义视图中获取属性值
注意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();
}
// ...
}
笔记
textSizeAttribute=textSizeAttribute.replaceAll(“[^\\d\\\.]+”,”)发送;textSize=Float.parseFloat(textSizeAttribute)代码>就这样。它不是最健壮的,但对于常规的文本大小输入来说应该可以很好地使用。确保在使用完该类型Darray后将其回收。a.recycle()
<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>
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();
}
// ...
}