1.attrs文件注意事项: (1)每个 attr (属性)名称在应用程序范围内必须唯一,既无论定义几个资源文件,无论定义几个styleable,声明必须唯一 (2)如果一个 attr 后面仅仅有一个 name ,那么这就是引用;如果不光有 name 还有 format那就是声明。test1的title 是属性的声明,其不能在其他 styleable 中再次声明;test的title则是属性的引用,其声明是在test1 中。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="test1">
<attr name="key" format="string"/>
<attr name="title" format="string" /><!--参考下面的title注释-->
<attr name="summary" format="string" />
<attr name="layout" />
<attr name="widgetLayout" format="reference" />
<attr name="titleMarginEnd" format="dimension"/>
<attr name="titleWidth" format="dimension"/>
<attr name="defValue" format="string|boolean|integer"/>
<attr name="persistent" format="boolean"/>
<attr name="tipText" format="string"/>
</declare-styleable>
<declare-styleable name="test">
<attr name="title" /><!--只要指定format,不管和上面的format类型相同还是不同,编译时就会上面的title冲突,不指定format,编译时不会报错-->
<attr name="layout_width" format="reference" />
<attr name="values" format="reference" />
<attr name="spinnerWidth" format="dimension"/>
<attr name="spinnerHeight" format="dimension"/>
<attr name="spinnerMode" format="string"/>
<attr name="id" format="reference" />
</declare-styleable>
<!-- 注意:1.attrs文件不能指定名字相同的attr(除非一个指定format,另一个不指定,参考上图的title) -->
</resources>
2.layout文件
<?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:gs="http://schemas.android.com/apk/res-auto" xmlns:stackdump="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"> <!--gs和stackdump是随意指定的名字--> <com.stackdump.attrs.widget.CmccSpinnerPreference android:id="@+id/size_pref" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="parent" app:layout_constraintEnd_toStartOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" gs:spinnerMode="hello_test" stackdump:title="hello" /> </androidx.constraintlayout.widget.ConstraintLayout>
3.自定义控件CmccSpinnerPreference.ajva
package com.stackdump.attrs.widget; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.LinearLayout; import android.widget.Spinner; import com.stackdump.attrs.R; import androidx.annotation.Nullable; /** * Author:stackdump * Date:20-2-10 */ public class CmccSpinnerPreference extends LinearLayout { private static final String TAG = "CmccSpinnerPreference"; private CharSequence[] mEntries; private CharSequence[] mEntryValues; private String mValue; private String mSummary; private String mTitle; private int mSelectedEntryIndex; private boolean mValueSet; private float spinnerWidth; private float spinnerHeight; private boolean dialogMode; private Spinner mSpinner; private View.OnFocusChangeListener mOnFocusChangeListener; public CmccSpinnerPreference(Context context) { this(context, null); } public CmccSpinnerPreference(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CmccSpinnerPreference(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.test, defStyleAttr, 0);//此处为了证明test名称可随意命名,特意没有与自定义控件的名称保持相同 mTitle = a.getString(R.styleable.test_spinnerMode); a.recycle(); TypedArray a1 = context.obtainStyledAttributes(attrs, R.styleable.test1, defStyleAttr, 0); mSummary = a1.getString(R.styleable.test1_title); a1.recycle(); Log.d("info","stackdump mTitle:"+mTitle+" mSummary:"+mSummary); } }
4.log打印: stackdump mTitle:hello_test mSummary:hello
0