Thuộc tính tùy chỉnh trong tệp kiểu tệp


178

Tôi đã tạo một tiện ích tùy chỉnh và tôi đang khai báo nó trong layout.xml. Tôi cũng đã thêm một số thuộc tính tùy chỉnh trong attr.xml. Tuy nhiên, khi cố gắng khai báo các thuộc tính này theo kiểu trong tệp style.xml, nó mang lại cho tôiNo resource found that matches the given name: attr 'custom:attribute'.

Tôi đã đặt xmlns:custom="http://schemas.android.com/apk/res/com.my.package"tất cả các thẻ trong tệp style.xml, bao gồm <?xml>, <resources><style>, nhưng nó vẫn gây ra lỗi tương tự, rằng nó không thể tìm thấy không gian tên XML tùy chỉnh của tôi.

Tuy nhiên, tôi có thể sử dụng không gian tên của mình để gán các thuộc tính theo cách thủ công cho khung nhìn trong layout.xml của tôi, vì vậy không có gì sai với không gian tên. Vấn đề của tôi nằm ở việc làm cho Styles.xml nhận thức được attr.xml của tôi.


1
cutsom:xmlns=...?? không nên xmlns:cutsom=...?
Selvin

Vâng, đó là những gì tôi nhận được khi không sử dụng bản sao / dán cảm ơn
styler1972

Câu trả lời:


362

Tôi đã hiểu rồi! Câu trả lời là KHÔNG chỉ định không gian tên theo kiểu.

<?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
Lỗi biến mất, nhưng chế độ xem của tôi không chấp nhận giá trị thuộc tính, trong khi đó, nó áp dụng các thuộc tính (không tùy chỉnh) khác. Thuộc tính đặc biệt của tôi là một enum. Đoạn mã trên có làm việc cho bạn không?
Paul Lammertsma

@PaulLammertsma Tôi đang sử dụng một enum và điều này dường như cũng không hiệu quả với tôi. Nếu bạn không có thuộc tính xmlns không gian tên tùy chỉnh, bạn thực sự có thể nhập bất kỳ giá trị nào bạn muốn cho thuộc tính tên mục và nó sẽ biên dịch.
David Snabel-Caunt

@DavidCaunt Cuối cùng tôi đã có được những gì tôi đang làm về chức năng. Cuối cùng tôi đã sử dụng một chuỗi cho declare-stylablethay vì một enum. Tôi không chắc tại sao enums không hoạt động, nhưng công việc này là đủ tốt cho tôi.
Paul Lammertsma

3
Điều này thậm chí không biên dịch cho tôi, sử dụng API lv 16.
David Miler

3
Trong khi điều này hoạt động, tôi nghi ngờ rằng sẽ có một vấn đề khi giải quyết các thuộc tính nếu một thuộc tính có cùng tên tồn tại trong hai hoặc nhiều gói nhưng với các tên gói khác nhau.
AndroidDev

43

câu trả lời trên có hiệu quả với tôi, tôi đã thử thay đổi litte, tôi tuyên bố có thể tạo kiểu cho một lớp trong phần tử tài nguyên.

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

trong khai báo có thể điều chỉnh được , thuộc tính name đã tham chiếu một tên lớp, vì vậy tôi đã có một lớp gọi xem "com.my.package.name.V verticalView", nó đại diện cho khai báo này phải được sử dụng trong verticalView hoặc các lớp con của verticalView. vì vậy chúng ta có thể khai báo kiểu như thế này:

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

đó là lý do tại sao chúng tôi không khai báo không gian tên ở phần tử tài nguyên, nó vẫn hoạt động.


11

giá trị / style.xml

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

giá trị / attrs.xml

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

giá trị / màu sắc

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

giá trị / dimens.xml

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

Sử dụng

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

nhập mô tả hình ảnh ở đây

BẢN GIỚI THIỆU


10

Sửa đổi styler và vince làm việc cho tôi. Tôi muốn chỉ ra rằng lời giải thích của @ vince có thể không hoàn toàn chính xác.

Để kiểm tra giả thuyết rằng thuộc tính name của tên declare-styleablephù hợp với lớp của chế độ xem tùy chỉnh đang cho phép chúng ta truy cập thuộc tính tùy chỉnh mà không có không gian tên tôi đã thay đổi tên của declare-styleable(chế độ xem tùy chỉnh được đặt tên TestViewFont:

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

Sau đó, tôi đã thay đổi obtainStyledAttributescuộc gọi trong chế độ xem tùy chỉnh để phản ánh điều này:

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

Mã vẫn chạy. Vì vậy, tôi không nghĩ rằng đó là một loại nội tâm declare-styleablecủa lớp mà nó được đặt theo tên.

Do đó, tôi tin rằng bất kỳ thuộc tính tùy chỉnh nào cũng có thể được sử dụng để khai báo một kiểu mà không cần tham chiếu đến một không gian tên.

Bất kể, cảm ơn tất cả những người giúp đỡ, nó đã giải quyết vấn đề của tôi.


Trên thực tế, các thuộc tính chia sẻ cùng một không gian tên, cho dù chúng được khai báo trong một declare-styleablekhối hay không. (xin lỗi, tôi không thể tìm thấy trang tham chiếu cho trò chơi này) Ngoại trừ các thuộc tính từ androidkhông gian tên, bạn chỉ nên chỉ ra tên thuộc tính.
pr-shadoko

3
  • Xác định một số thuộc tính

<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • Sử dụng nó trong tập tin bố trí như

<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • Cuối cùng sử dụng nó trong tập tin phong cách

    Sự khác biệt giữa tệp kiểu và tệp bố cục là chúng tôi không thêm prefiex app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

Hãy thử nó, có một ngày tốt đẹp, điều này làm việc cho tôi.


2

Trong trường hợp nó giúp được bất kỳ ai khác, lỗi của tôi là lớp chế độ xem tùy chỉnh của tôi đã gọi AttributionSet.getAttributionValue, vd

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

... Điều đó dẫn đến việc thuộc tính tùy chỉnh của tôi không được đọc trong chế độ xem tùy chỉnh của tôi.

Cách khắc phục là sử dụng obtainStyledAttributestrong chế độ xem tùy chỉnh của tôi:

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

Một gợi ý rằng điều này đang hoạt động chính xác là bạn có thể nhấp Ctrl / Apple + vào R.styleable.MyTextViewStyleable_customFontđể được đưa thẳng đến định nghĩa attrs.xml của bạn.

Phải mất một thời gian tôi mới phát hiện ra sự khác biệt quan trọng này giữa mã của tôi và các ví dụ khác, vì thuộc tính tùy chỉnh hoạt động tốt khi được truyền trực tiếp qua XML bố cục (thay vì thông qua một kiểu).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.