访问AttributeSet中的attrs以获取自定义组件

Jos*_*ach 20 java android textview android-relativelayout

我有一个包含两个TextView的自定义组件,它们具有自定义大小设置方法(两个文本视图的比例约为1:2).由于这是RelativeLayout的子类,它没有textSize属性,但我想知道是否仍然可以android:textSize在该组件的XML实例化中设置该属性,然后textSize从AttributeSet中获取属性以使用setSize()在构造函数中使用我的自定义方法.

我已经看到了使用自定义属性执行此操作的技术,但是如果我想获取已经在android词典中的属性怎么办?

ser*_*zel 70

对的,这是可能的;

假设您的RelativeLayout声明(在xml中)使用14sp定义了textSize:

android:textSize="14sp"
Run Code Online (Sandbox Code Playgroud)

在自定义视图的构造函数(接收AttributeSet的构造函数)中,您可以从Android的命名空间中检索属性:

String xmlProvidedSize = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "textSize");
Run Code Online (Sandbox Code Playgroud)

xmlProvidedSize的值将类似于"14.0sp",并且可能只需要一点字符串编辑就可以提取数字.


声明自己的属性集的另一个选项是冗长的,但它也是可能的.

所以,你有自定义视图,你的TextView声明如下:

public class MyCustomView extends RelativeLayout{

    private TextView myTextView1;
    private TextView myTextView2;

// rest of your class here
Run Code Online (Sandbox Code Playgroud)

大...

现在,您还需要确保自定义视图覆盖AttributeSet中包含的构造函数,如下所示:

public MyCustomView(Context context, AttributeSet attrs){   
    super(context, attrs);
    init(attrs, context);  //nice, clean method to instantiate your TextViews// 
}
Run Code Online (Sandbox Code Playgroud)

好的,我们现在看一下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 //
}
Run Code Online (Sandbox Code Playgroud)

你可能想知道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>
Run Code Online (Sandbox Code Playgroud)

现在,您可以在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"     
    />
Run Code Online (Sandbox Code Playgroud)

请注意我如何将命名空间声明为"josh"作为CustomView属性集中的第一行.

我希望这有助于Josh,