Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 访问自定义组件的AttributeSet中的属性_Java_Android_Textview_Android Relativelayout - Fatal编程技术网

Java 访问自定义组件的AttributeSet中的属性

Java 访问自定义组件的AttributeSet中的属性,java,android,textview,android-relativelayout,Java,Android,Textview,Android Relativelayout,我有一个自定义组件,其中包含两个启用了自定义大小设置方法的文本视图(两个文本视图的比例约为1:2)。因为这是RelativeLayout的一个子类,所以它没有textSize属性,但我想知道是否仍然可以在该组件的XML实例化中设置android:textSize属性,然后从属性集中抓取textSize属性以用于我的自定义setSize()构造函数中的方法 我已经见过使用自定义属性来实现这一点的技术,但是如果我想获取android词典中已经存在的属性,该怎么办?是的,这是可能的 让我们假设您的Re

我有一个自定义组件,其中包含两个启用了自定义大小设置方法的文本视图(两个文本视图的比例约为1:2)。因为这是RelativeLayout的一个子类,所以它没有textSize属性,但我想知道是否仍然可以在该组件的XML实例化中设置
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();
    }

    // ...
}
笔记

如果我只想在现有的android名称空间中使用属性,比如android:textSize,该怎么办。实际上,我只想读取该属性是什么(即使RelativeLayout将忽略它),并使用数值(来自“14sp”的14)以编程方式设置子视图中的文本大小。有没有一种方法可以在不创建另一个模式的情况下获取该集合中现有的android属性?嘿,Josh,我在回答的顶部添加了如何检索android名称空间属性值。最好的,非常好。我几乎做到了:)我在以前的尝试中没有使用完整的名称空间。通过
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();
    }

    // ...
}