แอตทริบิวต์ที่กำหนดเองใน styles.xml


178

ฉันสร้างวิดเจ็ตที่กำหนดเองและฉันประกาศใน layout.xml ฉันได้เพิ่มคุณสมบัติที่กำหนดเองใน attr.xml ด้วย อย่างไรก็ตามเมื่อพยายามที่จะประกาศคุณลักษณะเหล่านี้ในสไตล์ใน styles.xml มันให้ฉันNo resource found that matches the given name: attr 'custom:attribute'.

ฉันต้องใส่xmlns:custom="http://schemas.android.com/apk/res/com.my.package"ในแท็กทั้งหมดใน styles.xml รวมทั้ง<?xml>, <resources>และ<style>แต่ก็ยังทำให้ผมมีข้อผิดพลาดเดียวกันว่ามันไม่สามารถหา namespace XML แบบกำหนดเองของฉัน

อย่างไรก็ตามฉันสามารถใช้เนมสเปซของฉันเพื่อกำหนดแอตทริบิวต์ให้กับมุมมองใน layout.xml ของฉันด้วยตนเองได้ดังนั้นจึงไม่มีอะไรผิดกับเนมสเปซ ปัญหาของฉันอยู่ที่การทำให้ styles.xml รับรู้ถึง attr.xml ของฉัน


1
cutsom:xmlns=...?? ไม่ควรจะเป็นxmlns:cutsom=...?
Selvin

ใช่นั่นคือสิ่งที่ฉันไม่ได้ใช้เพื่อคัดลอก / วางขอบคุณแม้ว่า
styler1972

คำตอบ:


362

ฉันคิดออก! คำตอบคือไม่ต้องระบุเนมสเปซในสไตล์

<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="CustomStyle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>

        <item name="custom_attr">value</item> <!-- tee hee -->
    </style>
</resources>

13
ข้อผิดพลาดจะหายไป แต่มุมมองของฉันไม่ได้ใช้ค่าแอททริบิวในขณะที่มันใช้แอททริบิวอื่น ๆ (ไม่ใช่แบบกำหนดเอง) คุณลักษณะเฉพาะของฉันคือ enum ตัวอย่างด้านบนใช้ได้กับคุณหรือไม่
Paul Lammertsma

@ พอลแลมเมอร์สมาฉันกำลังใช้ enum อยู่และนี่ก็ไม่ได้ผลสำหรับฉันเช่นกัน หากคุณไม่มีแอตทริบิวต์ xmlns namespace ที่กำหนดเองคุณสามารถพิมพ์ค่าใด ๆ ที่คุณต้องการสำหรับแอตทริบิวต์ชื่อรายการและมันจะรวบรวม
David Snabel-Caunt

@DavidCaunt ฉันไม่ในที่สุดได้รับสิ่งที่ผมทำงานเกี่ยวกับการทำงาน ในที่สุดฉันก็ใช้สตริงdeclare-stylableแทน enum ฉันไม่แน่ใจว่าทำไม enums ไม่ทำงาน แต่การแก้ไขนี้ดีพอสำหรับฉัน
Paul Lammertsma

3
สิ่งนี้ไม่ได้รวบรวมสำหรับฉันโดยใช้ API เลเวล 16
David Miler

3
ในขณะที่ใช้งานได้ฉันสงสัยว่าจะมีปัญหาในการแก้ไขแอตทริบิวต์หากมีแอตทริบิวต์ที่มีชื่อเดียวกันอยู่ในแพ็คเกจสองแพ็คเกจขึ้นไป แต่มีชื่อแพ็คเกจต่างกัน
AndroidDev

43

คำตอบข้างต้นใช้งานได้สำหรับฉันฉันลองเปลี่ยน litte ฉันประกาศสไตล์สำหรับคลาสในองค์ประกอบทรัพยากร

<declare-styleable name="VerticalView">
    <attr name="textSize" format="dimension" />
    <attr name="textColor" format="color" />
    <attr name="textBold" format="boolean" />
</declare-styleable>

ในแบบประกาศคุณสมบัติของชื่ออ้างอิงชื่อคลาสดังนั้นฉันมีการเรียกคลาสดู "com.my.package.name.VerticalView" มันเป็นตัวแทนประกาศนี้จะต้องใช้ใน VerticalView หรือ subclasses ของ VerticalView เพื่อให้เราสามารถประกาศสไตล์เช่นนี้:

<resources>
    <style name="verticalViewStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">36dip</item>

        <item name="textSize">28sp</item>  <!-- not namespace prefix -->
        <item name="textColor">#ff666666</item>
        <item name="textBold">true</item>
    </style>
</resources>

นั่นเป็นสาเหตุที่เราไม่ได้ประกาศ namespace ที่องค์ประกอบทรัพยากร แต่ก็ยังใช้งานได้


11

ค่า / styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="defaultButtonColor">@color/red</item>
    <item name="defaultButtonHeight">@dimen/dp_100</item>
</style>

ค่า / attrs.xml

<resources>
    <attr name="defaultButtonColor" format="reference" />
    <attr name="defaultButtonHeight" format="reference"/>
</resources>

ค่า / colors.xml

<resources>
    <color name="red">#f00</color>
</resources>

ค่า / dimens.xml

<resources>
    <dimen name="dp_100">100dp</dimen>
</resources>

การใช้

<Button
    android:layout_width="wrap_content"
    android:layout_height="?attr/defaultButtonHeight"
    android:text="Button"
    android:textColor="?attr/defaultButtonColor"
    />

ป้อนคำอธิบายรูปภาพที่นี่

การสาธิต


10

การปรับเปลี่ยนของ Styler และ vince นั้นเหมาะสำหรับฉัน ฉันต้องการชี้ให้เห็นว่าคำอธิบายของ @ vince อาจไม่ถูกต้องทั้งหมด

ในการทดสอบสมมติฐานว่าแอตทริบิวต์ name ของการdeclare-styleableจับคู่ชื่อของคลาสมุมมองที่กำหนดเองช่วยให้เราสามารถเข้าถึงแอตทริบิวต์ที่กำหนดเองโดยไม่มีเนมสเปซฉันเปลี่ยนชื่อของdeclare-styleable(ชื่อมุมมองที่กำหนดเองTestViewFont:

<declare-styleable name="TextViewFont2">
    <attr name="font" format="integer"/>
</declare-styleable>

จากนั้นฉันเปลี่ยนการobtainStyledAttributesโทรในมุมมองที่กำหนดเองเพื่อสะท้อนสิ่งนี้:

TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TextViewFont2, 0, 0);

รหัสยังคงทำงานอยู่ ดังนั้นฉันไม่คิดว่ามันเป็นการวิปัสสนาบางอย่างdeclare-styleableของชั้นเรียนที่ตั้งชื่อตาม

ดังนั้นฉันจึงเชื่อว่าแอตทริบิวต์ที่กำหนดเองใด ๆ สามารถใช้เพื่อประกาศสไตล์โดยไม่อ้างอิงถึงเนมสเปซ

ไม่ว่าจะเป็นการขอบคุณสำหรับความช่วยเหลือทั้งหมดมันช่วยแก้ไขปัญหาของฉันได้


ที่จริงแล้วแอ็ตทริบิวต์แบ่งใช้เนมสเปซเดียวกันไม่ว่าจะถูกประกาศในdeclare-styleableบล็อกหรือไม่ก็ตาม (ขออภัยฉันไม่พบหน้าอ้างอิงสำหรับสิ่งนี้ ... ) ยกเว้นคุณลักษณะจากandroidเนมสเปซคุณควรระบุชื่อแอตทริบิวต์เท่านั้น
pr-shadoko

3
  • กำหนดคุณสมบัติบางอย่าง

<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • ใช้ในรูปแบบไฟล์เช่น

<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • ในที่สุดใช้มันในไฟล์สไตล์

    ความแตกต่างระหว่างไฟล์สไตล์และไฟล์เลย์เอาต์คือเราไม่ได้เพิ่ม prefiex app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

ลองมีวันที่ดีนี้เหมาะกับฉัน


2

ในกรณีที่ช่วยใครก็ได้ข้อผิดพลาดของฉันคือคลาสการดูแบบกำหนดเองของฉันกำลังเรียกAttributeSet.getAttributeValueเช่น

String fontName = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "customFont");

... ซึ่งส่งผลให้แอตทริบิวต์ที่กำหนดเองของฉันไม่ถูกอ่านสำหรับมุมมองที่กำหนดเองของฉัน

การแก้ไขคือการใช้obtainStyledAttributesในมุมมองที่กำหนดเองของฉัน:

 TypedArray styleAttrs = context.obtainStyledAttributes(attrs, R.styleable.MyTextViewStyleable);
 String fontName = styleAttrs.getString(R.styleable.MyTextViewStyleable_customFont);

คำใบ้ว่าสิ่งนี้ทำงานได้อย่างถูกต้องคือคุณสามารถกด Ctrl / Apple + R.styleable.MyTextViewStyleable_customFontเพื่อไปยังคำนิยามของ attrs.xml

ฉันใช้เวลาสักครู่เพื่อมองเห็นความแตกต่างที่สำคัญระหว่างรหัสของฉันกับตัวอย่างอื่น ๆ เนื่องจากแอตทริบิวต์ที่กำหนดเองทำงานได้ดีเมื่อส่งผ่านโดยตรงผ่านเค้าโครง XML (แทนที่จะเป็นสไตล์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.