Java Android自定义属性返回null

Java Android自定义属性返回null,java,android,attributes,Java,Android,Attributes,我正在尝试学习如何在Android Studio中使用自定义属性。我跟随了一些关于这个主题的教程,尽管我努力了,但似乎没有任何效果。我创建了一个代码来说明这个问题 我创建了简单的自定义视图,它不表示任何内容,只获取样式化属性。这是我的customView代码: package com.example.mytestattributes; import android.content.Context; import android.content.res.TypedArray; import an

我正在尝试学习如何在Android Studio中使用自定义属性。我跟随了一些关于这个主题的教程,尽管我努力了,但似乎没有任何效果。我创建了一个代码来说明这个问题

我创建了简单的自定义视图,它不表示任何内容,只获取样式化属性。这是我的customView代码:

package com.example.mytestattributes;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.Nullable;

public class customView extends View {
    public customView(Context context) {
        super(context);
        init(null);
    }

    public customView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }
    private void init(@Nullable AttributeSet attrs){
        if(attrs!=null){
            Log.d("INIT", "attribute set found");
            TypedArray ta = getContext().obtainStyledAttributes(R.styleable.customView);
            Log.d("LENGHT OF TA: ", ta.length()+"");
            Log.d("testString has value", ta.hasValue(R.styleable.customView_testString)+"");
            Log.d("testInteger has value", ta.hasValue(R.styleable.customView_testInteger)+"");
            Log.d("testBoolean has value", ta.hasValue(R.styleable.customView_testBoolean)+"");
            Log.d("testColor has value", ta.hasValue(R.styleable.customView_testColor)+"");
            Log.d("testDimension has value", ta.hasValue(R.styleable.customView_testDimension)+"");
            Log.d("testEnum has value", ta.hasValue(R.styleable.customView_testEnum)+"");

            Log.d("Return testDimension: ", ""+ta.getDimensionPixelSize(R.styleable.customView_testDimension,0));
            Log.d("Return testDimension: ", ""+ta.getDimension(R.styleable.customView_testDimension,0));

        }else{
            Log.d("INIT", "no attribute set found");
        }


    }
}
代码编译后,输出为:

D/INIT: attribute set found
D/LENGHT OF TA:: 6
D/testString has value: false
D/testInteger has value: false
D/testBoolean has value: false
D/testColor has value: false
D/testDimension has value: false
D/testEnum has value: false
D/Return testDimension:: 0
D/Return testDimension:: 0.0
类型化数组的长度是正确的,这意味着程序可以看到属性,但当我要求它检查属性是否有值时,结果是错误的。因此,任何读取此属性的尝试都会返回默认值。在示例代码中,我只包含了getDimension,但对所有其他get方法都适用

这是我的attrs.xml,我在其中定义了attibutes:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="customView">
        <attr name="testString" format="string|reference"/>
        <attr name="testInteger" format="integer"/>
        <attr name="testBoolean" format="boolean"/>
        <attr name="testColor" format="color|reference"/>
        <attr name="testDimension" format="dimension"/>
        <attr name="testEnum" format="enum">
            <enum name="var1" value="1"/>
            <enum name="var2" value="2"/>
        </attr>
    </declare-styleable>
</resources>

我尝试在Activity_Main.xml中传递值:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.mytestattributes.customView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:testBoolean="true"
        app:testDimension="200dp"
        app:testColor="@color/colorAccent"
        app:testEnum="var1"
        app:testInteger="15"
        app:testString="@string/app_name"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java是未修改的空活动类。 我知道一些人在几年前也有类似的问题,但是没有有效的答案。 有人知道这个代码有什么问题吗?
我正在使用API 17。

经过一些修补,我更换了线路:

TypedArray ta = getContext().obtainStyledAttributes(R.styleable.customView);

问题解决了。 或者,我还发现,如果TypedArray再次失败,则可以直接从ATTR获取值,使用:

attrs.getValue(int index) 
必须注意的是,属性集中属性的索引与类型化数组中的索引不同,因为它还包括标准的android属性。可通过以下方式检查索引:

            for (int i = 0; i < attrs.getAttributeCount(); i++) {
                Log.d("ATTRS", i+ ": " + attrs.getAttributeName(i)+"");
            }
for(int i=0;i
传递资源时,为什么不将
引用
声明为属性格式之一<代码>用于字符串,代码>用于颜色。我根据您的建议修改了代码,但它没有改变任何内容。输出仍然是错误的。:facepalm:,非常感谢!
            for (int i = 0; i < attrs.getAttributeCount(); i++) {
                Log.d("ATTRS", i+ ": " + attrs.getAttributeName(i)+"");
            }