web-dev-qa-db-ja.com

カスタムビューのattrs.xmlの同じ名前の属性

同じ名前の属性を共有するいくつかのカスタムビューを作成しています。 _<declare-styleable>_のそれぞれの_attrs.xml_セクションで、属性に同じ名前を使用したい:

_<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView1">
        <attr name="myattr1" format="string" />
        <attr name="myattr2" format="dimension" />
        ...
    </declare-styleable>

    <declare-styleable name="MyView2">
        <attr name="myattr1" format="string" />
        <attr name="myattr2" format="dimension" />
        ...
    </declare-styleable>
</resources>
_

_myattr1_と_myattr2_が既に定義されているというエラーが表示されます。 _myattr1_および_myattr2_のformat属性を_MyView2_で省略する必要があることがわかりましたが、そうすると、コンソールで次のエラーが表示されます。

_[2010-12-13 23:53:11 - MyProject] ERROR: In <declare-styleable> MyView2, unable to find attribute 
_

私はこれを達成する方法がありますか、おそらく何らかの名前空間(推測する)ですか?

157
Venator85

Solution:単純に両方のビューから共通の属性を抽出し、<resources>ノードの子として直接追加します。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="myattr1" format="string" />
    <attr name="myattr2" format="dimension" />

    <declare-styleable name="MyView1">
        <attr name="myattr1" />
        <attr name="myattr2" />
        ...
    </declare-styleable>

    <declare-styleable name="MyView2">
        <attr name="myattr1" />
        <attr name="myattr2" />
        ...
    </declare-styleable>
</resources>
351
Venator85

上記の解決策がAndroid Studioでうまくいかなかったため、この回答を投稿しています。カスタムビューでカスタム属性を共有する必要があるため、 Androidスタジオですが、運がありませんでした。だから私は実験し、それを行う方法を探します。同じ問題を探している人の助けになるかもしれません。

  <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <!-- parent styleable -->
     <declare-styleable name="MyView">
         <attr name="myattr1" format="string" />
         <attr name="myattr2" format="dimension" />
     </declare-styleable>

     <!-- inheriting parent styleable -->
     <!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
    <declare-styleable name="MyView1" parent="MyView">
        <attr name="myattr1" />
        <attr name="myattr2" />
        <attr name="myBackgroundColor" format="color"/>
    </declare-styleable>


    <!-- inheriting parent styleable -->
    <!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
    <declare-styleable name="MyView2" parent="MyView">
        <attr name="myattr1" />
        <attr name="myattr2" />
        <attr name="myfont" format="string"/>
        ...
    </declare-styleable>
</resources>

これは私にとって完全に機能します。親をスタイル可能にする必要があり、次にその親をスタイル可能に継承する必要があります。たとえば、上記で行ったように、親のスタイル可能な名前MyViewで、これをそれぞれMyView1やMyView2などの他のスタイル可能な名前に継承します。

41
Priya Singhal

Priya Singhalが答えたように、Android Studioでは、独自のスタイル名内で共通の属性名を定義する必要があります。これらはルートに存在できません。

ただし、他にも注意すべき点がいくつかあります(そのため、回答も追加しています)。

  • 一般的なスタイルには、ビューと同じ名前を付ける必要はありません。 ( this answer に感謝します。)
  • 親との継承を使用する必要はありません。

これは、同じ属性を共有する2つのカスタムビューを持つ最近のプロジェクトで私が行ったことです。カスタムビューに属性の名前がまだあり、formatが含まれていない限り、コードから通常どおりそれらにアクセスできます。

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- common attributes to all custom text based views -->

    <declare-styleable name="TextAttributes">
        <attr name="text" format="string"/>
        <attr name="textSize" format="dimension"/>
        <attr name="textColor" format="color"/>
        <attr name="gravity">
            <flag name="top" value="48" />
            <flag name="center" value="17" />
            <flag name="bottom" value="80" />
        </attr>
    </declare-styleable>

    <!-- custom text views -->

    <declare-styleable name="View1">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

    <declare-styleable name="View2">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

</resources>

合理化された例

実際、カスタム名の下に属性を配置する必要さえありません。少なくとも1つのカスタムビューに対してそれらを定義する(formatを与える)限り、どこでも(formatなしで)使用できます。したがって、これも機能します(そしてよりきれいに見えます):

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="View1">
        <attr name="text" format="string"/>
        <attr name="textSize" format="dimension"/>
        <attr name="textColor" format="color"/>
        <attr name="gravity">
            <flag name="top" value="48" />
            <flag name="center" value="17" />
            <flag name="bottom" value="80" />
        </attr>
    </declare-styleable>

    <declare-styleable name="View2">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

</resources>

しかし、大規模なプロジェクトの場合、これは面倒になる可能性があり、それらを単一の場所の上部で定義する方が良いかもしれません(推奨されるように here )。

24
Suragch

ルイスのおかげで私は同じ問題を抱えていましたが、あなたの継承ソリューションは以下のようにそれを行うためのヒントを与えてくれました、それはうまくいきます。私はそれが誰かを助けることを願っています

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes -->
     <attr name="myattr1" format="string" />
     <attr name="myattr2" format="dimension" />

 <!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" >
    <attr name="myattr1" />
    <attr name="myattr2" />
    <attr name="myBackgroundColor" format="color"/>
</declare-styleable>

<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
    <attr name="myattr1" />
    <attr name="myattr2" />
    <attr name="myfont" format="string"/>
    ...
</declare-styleable>
7
Hanieh Variani

誰かが利用可能な解決策を試みた後、まだこの問題で立ち往生している場合に備えて。 subtitle形式のstring属性を追加することに固執しました。

私の解決策は、形式を削除することです。

前:

<attr name="subtitle" format="string"/>

後:

<attr name="subtitle"/>

1
Ahmad Muzakki