Özel görünüm için attrs.xml dosyasında aynı adlı öznitelikler


180

Aynı adlı bazı öznitelikleri paylaşan birkaç özel görünüm yazıyorum. İlgili <declare-styleable>bölümlerinde, attrs.xmlöznitelikler için aynı adları kullanmak istiyorum:

<?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>

Bunu söyleyen bir hata alıyorum myattr1ve myattr2zaten tanımlanmış. Ben ihmal gerektiğini tespit formatözelliğine yönelik myattr1ve myattr2içinde MyView2, ama bunu, ben konsolda aşağıdaki hatayı edinin:

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

Bunu başarabilmemin bir yolu var mı, belki bir çeşit isim aralığı (sadece tahmin etmek)?

Yanıtlar:


401

Çözüm: Ortak özellikleri her iki görünümden de çıkarın ve bunları doğrudan <resources>düğümün alt öğeleri olarak ekleyin :

<?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>

11
myattr1dize MyView1içeri ve tamsayı içeri girdiğinde ne olur MyView2?
foxx1337

4
Ben öyle düşünmüyorum, örneğin 'oryantasyon' özelliğine sahip olabiliriz ve bazı görünümler için 'yatay' / 'dikey' ve diğer 'manzara' / 'portre' / 'kare'. Benim açımdan, Android'de bir hata (veya en azından tutarsız davranış) olduğunu unutmayın (şunu unutmayın: 1. stylable öznitelikleri her zaman önek = görünüm adı ile başlar ve 2. bu tür görünümler için ayrı kütüphane projeleri oluşturursanız her şey iyi çalışır )
se.solovyev

4
Bu cevabı takip ERROR: In <declare-styleable> com_app_view_widget, unable to find attribute customAttr ettiğimde beyan etmeye çalıştığım tüm görüşler için. Herhangi bir fikir?
Dapp

45
@Google: Berbat tasarım
Glenn Bech

6
@ foxx1337 Sadece kullanın <attr name="myattr1" format="string|integer" />. Benim için çalışıyor.
Mygod

58

Yukarıdaki cevabı Android Studio'da benim için çalışmadığı için bu cevabı gönderiyorum. Özel özniteliklerimi özel görünümlerim arasında paylaşmam gerekiyor, bu yüzden Android Studio'da yukarıdaki çözümü denedim ama şansım yoktu. Ben de denemek ve bunu yapmak için bir yol gitmek. Umarım aynı sorunu arayan birine yardımcı olabilir.

  <?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>

Bu benim için tamamen işe yarıyor. Bir Ebeveyn'i stilize etmeliyiz ve sonra o ebeveyni stilize edebilmeliyiz. Örneğin, yukarıda yaptığım gibi: Üst stillenebilir MyView adı ve bunu sırasıyla MyView1 ve MyView2 gibi diğer stillenebilirlerime devralmış.


1
Bu benim için çalıştı. Kabul edilen yanıttan kodda ayıklanan özniteliklere başvurmak için bir yol bulamadım.
Nemanja Kovacevic

Hmm .. bu garip .. kabul edilen çözüm benim için iyi çalışıyor gibi görünüyor (targetSdkVersion 27). Belki de "metin" gibi öznitelikler yaygın olduğundan ve başka bazı attrs.xml dosyalarında mevcut olabilir.
Aba

Muhtemelen nadir bir isim denedim ve kabul edilen çözüm hala benim için çalıştı.
Aba

İlk yorumu kabul ediyorum! TypedArray öğesinden ayıklanan bir attreye başvurmanın bir yolu yoktur. Bu nedenle bir stil sahibi ebeveyn tanımlamanız gerekir
reavcn

işe Bunun için bu ebeveynde niteliği değil çocukta hitap etmeyi unutmayın (sınıf için MyView2sağa: R.styleable.MyView2_myattr1Yanlış: R.styleable.MyView_myattr1)
vigilancer

28

Priya Singhal'ın yanıtladığı gibi, Android Studio ortak özellik adlarının kendi stil adlarında tanımlanmasını gerektirir. Artık kökte olamazlar.

Ancak, dikkat edilmesi gereken birkaç şey daha var (bu yüzden de bir cevap ekliyorum):

  • Ortak stillerin görünümle aynı şekilde adlandırılması gerekmez. ( Bu cevaba işaret ettiğin için teşekkürler .)
  • Bir ebeveyn ile miras kullanmanıza gerek yoktur.

Misal

Her ikisi de aynı öznitelikleri paylaşan iki özel görünüme sahip yeni bir projede yaptığım şey. Özel görünümler hala özniteliklerin adlarına sahip olduğu ve bir içermediği formatsürece, koddan normal olarak onlara erişebilirim.

<?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>

Kolaylaştırılmış örnek

Aslında, öznitelikleri özel bir isme koymam bile gerekmiyor. Onları formaten az bir özel görünüm için tanımladığım sürece (onlara a ), onları her yerde (olmadan format) kullanabilirim. Bu da işe yarıyor (ve daha temiz görünüyor):

<?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>

Büyük bir proje için, bu dağınık olabilir ve bunları tek bir yerde en üstte tanımlamak daha iyi olabilir ( burada önerildiği gibi ).


Mirasta yanlış olan ne? Ben stilleri ilişkilendirilmiş özel görünüm hiyerarşileri var, sadece ilişkilerini ve orada tanımlanan belirli öğeleri adlandırarak ilişkili stil tanımlarında çıkarılabilir bu ilişki yansıtmıyor (birkaç stilize ve birkaç diğerine ait olduğunu fark). parentÖzniteliği açıkça belirtmeyi tercih ederim, ancak kullanımını öneren birçok yayın görmedim.
samis

@samis, bir süredir bunun üzerinde çalışmadım, ama kullanmakla ilgili yanlış bir şey bilmiyorum parent. Sanırım sadece gerekli olmadığını söylüyordum.
19'da Suragch

Gerekli değil, sadece temel sınıfa koymak istemediğim ek bir özelliğin etrafına sarılmış başka bir alt sınıf yaptım. Ayrımı belirtmek için sadece yorumları ve adlandırma kurallarını kullanıyorum.
samis

8

Teşekkürler Lewis Ben de aynı sorunu vardı, ve miras çözüm bana aşağıdaki gibi yapmak için ipucu verdi ve iyi çalışıyor. Ben sadece yukarıda ortak nitelikleri beyan ve biçimlendirme olmadan tekrar stil beyanı gövdesinde yeniden yazmak. Umarım birine yardım eder

<?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>


1

Kullanılabilir çözümü denedikten sonra birisinin hala bu sorunla karşılaşması durumunda. İle subtitleöznitelik ekle ile sıkışmışstringBiçim .

Benim çözüm biçimini kaldırmak.

önce:

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

sonra:

<attr name="subtitle"/>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.