Androidでカスタムattributeの作り方


レイアウトを実装するときに
attributeをカスタマイズして?attribute_nameで利用する方法があると知った

そんなわけで試しにやってみた


・style.xml

<style name="MasterkaTextView" parent="Theme.AppCompat.Light">
    <item name="masterka3Color">@android:color/black</item>
</style>

<style name="MasterkaLayout">
    <item name="masterkaColor">@android:color/holo_blue_bright</item>
</style>

・attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MasterkaView">
        <attr name="masterkaColor" format="reference" />
        <attr name="masterka3Color" format="reference" />
    </declare-styleable>
</resources>

・layout.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:id="@+id/constraintLayout"
    android:theme="@style/MasterkaLayout"
    android:background="?masterkaColor"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.PlaceholderFragment">

    <!-- ?masterkaColorも動く -->
    <TextView
        android:id="@+id/section_label"
        android:gravity="center"
        android:theme="@style/MasterkaTextView"
        android:background="?masterka3Color"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="1" />

</androidx.constraintlayout.widget.ConstraintLayout>

・実装の説明
カスタムattributeを定義して
カスタムthemeに同じ名前のパラメーターを定義する
これをandroid:themeでview or activityに追加して
?attribute_nameでアクセスする。
attributeとして定義しないと?でアクセスできない。

このように実装することで定義してあるthemeのパラメーターしか使えなくなるので意味を定義できるようになる

また、themeなので親で定義すれば子でも使える

・注意点
themeを継承するか何も継承しない場合のみ動くっぽい
TextAppearance.AppCompat.Largeのようなstyleを継承した場合は、
以下のエラーが出てクラッシュする
Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index ホゲホゲ: TypedValue{t=ほげほげ}

関連記事:

Pocket