“? Android: attr / activeBackgroundIndicator” hoạt động như thế nào?


86

Tôi đang tìm cách làm nổi bật mục đã chọn trong danh sách khi hiển thị thanh hành động theo ngữ cảnh cho lựa chọn và giải pháp tôi tìm thấy là đặt android:backgroundthuộc tính xml của bố cục hàng của tôi thành "?android:attr/activatedBackgroundIndicator".

Tuy nhiên, cài đặt này hoạt động như thế nào?

  1. cơ chế liên quan là gì?
  2. các phần tử cú pháp như "?", "attr", "activeBackgroundIndicator" nghĩa là gì?
  3. ý nghĩa của "enableBackgroundIndicator" được định nghĩa ở đâu?

Câu trả lời:


221

Nếu bạn đang ở trong tâm trạng pháp y thì đây là cách đào sâu và tìm hiểu những gì đang xảy ra.

android:background="?android:attr/activatedBackgroundIndicator"?

Theo trực giác, điều này có nghĩa là đặt nền thành một số có thể vẽ được.

Nhưng chúng ta hãy phân tích điều này hơn nữa để xem làm thế nào chúng ta đến được với cái có thể vẽ bí ẩn của mình.

Nói một cách chính xác, nó có nghĩa là "đặt thuộc tính nền thành thuộc tính" activeBackgroundIndicator " đề cập đến trong chủ đề hiện tại .

Nếu bạn hiểu phần "đề cập đến trong chủ đề hiện tại", về cơ bản bạn đã hiểu mọi thứ đang diễn ra đằng sau các trang bìa.

Về cơ bản, activeBackgroundIndicator không phải là một drawable thực tế mà là một tham chiếu đến một drawable . Vậy thuộc tính "activeBackgroundIndictor" thực sự được định nghĩa ở đâu?

Nó được xác định trong thư mục sdk của bạn trong một tên tệp attrs.xml . Ví dụ:

path_to_android_sdk / platform / android-17 / data / res / values ​​/ attrs.xml

Nếu mở tệp đó, bạn sẽ khai báo như sau:

<attr name="activatedBackgroundIndicator" format="reference" />

attrs.xml là nơi bạn khai báo tất cả các thuộc tính mà sau này bạn sẽ sử dụng trong chế độ xem xml của mình. Lưu ý rằng chúng tôi đang khai báo thuộc tính và kiểu của nó chứ không thực sự gán giá trị ở đây .

Giá trị thực được gán trong themes.xml . Tệp này được đặt tại:

path_to_android_sdk / platform / android-17 / data / res / values ​​/ themes.xml

Nếu bạn mở tệp đó, bạn sẽ thấy nhiều định nghĩa tùy thuộc vào chủ đề bạn đang sử dụng . Ví dụ, đây là các định nghĩa cho tên chủ đề Theme, Theme.Light, Theme.Holo, Theme.Holo.Light tương ứng:

<item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_dark</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_light</item>

Bây giờ chúng tôi có những ngăn kéo bí ẩn của chúng tôi. Nếu bạn chọn cái đầu tiên, nó được xác định trong thư mục có thể vẽ tại:

path_to_android_sdk / platform / android-17 / data / res / drawable / active_background.xml

Nếu bạn mở tệp đó, bạn sẽ thấy định nghĩa của tệp có thể vẽ, điều quan trọng là bạn phải hiểu điều gì đang xảy ra.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:drawable="@android:drawable/list_selector_background_selected" />
    <item android:drawable="@color/transparent" />
</selector>

Ở đây chúng ta đang định nghĩa một drawable với hai trạng thái - trạng thái mặc định chỉ là nền trong suốt và nếu trạng thái là "state_actiised" thì có thể drawable của chúng ta là "list_selector_background_selected".

xem liên kết này để biết thông tin cơ bản về các vật có thể kéo và trạng thái.

"list_selector_background_selected" là một tệp png có 9 bản vá nằm trong thư mục drawable-hdpi.

Bây giờ bạn có thể thấy lý do tại sao chúng tôi đã xác định activeBackgroundIndicator làm tài liệu tham khảo thay vì liên kết trực tiếp đến tệp có thể vẽ - nó cho phép bạn chọn tệp có thể vẽ phù hợp tùy thuộc vào chủ đề của bạn.


3
Một câu trả lời để thống trị tất cả. Vì vậy, về cơ bản nếu một người tạo một XML với các bộ chọn giống nhau, anh ta có thể tạo "Công cụ hỗ trợ kích hoạt" của riêng mình?
Gee.E

1
chính xác - bạn có thể xác định lại nó trong theme tùy chỉnh của mình. xml b / c là thuộc tính tham chiếu.
numan salati

Câu trả lời này đã giúp tôi tìm ra cách đặt một có thể kéo tùy chỉnh trên mục danh sách ngăn điều hướng của tôi.
Tastybrownies

Đây là một nguồn tài nguyên tuyệt vời để bắt đầu thực hiện công việc tùy chỉnh selectorbằng cách sử dụng đồ có thể kéo được. Sau khi đọc phần này, tôi đã sử dụng Style Attribute Docs để điền vào các phần còn lại.
Maurizio

1
Bạn có thể cung cấp một ví dụ về cách ghi đè chỉ báo nền này không? Của tôi không hoạt động: / <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar"> <item name = "android: activeBackgroundIndicator"> @ drawable / active_background </item> </style> active_background.xml : <selector xmlns: android = " schemas.android.com/apk/res/android "> <item android: state_actiised = "true" android: drawable = "@ color / yellow" /> <item android: drawable = "@ android: color / transparent "/> </selector>
vandus

13

Tôi tự hỏi điều này cũng tại một thời điểm. Một lượng lớn tài nguyên Android dường như giống như một hộp đen và không thể nhìn thấy chúng trực tiếp. Tôi có thể thiếu chúng ở đâu đó, nhưng tôi không thể tìm thấy chúng trong mã nguồn SDK. Đây là những gì tôi biết.

  • android:background sẽ có một kéo.
  • Cú pháp theo kiểu

    Phải là một tham chiếu đến một tài nguyên khác, ở dạng "@ [+] [package:] type: name" hoặc đến một thuộc tính chủ đề ở dạng "? [Package:] [type:] name"

Trong trường hợp này, ?dấu hiệu cho thấy một chủ đề trong gói androidvà nó thuộc loại attrcó tên activatedBackgroundIndicator.

Bạn cũng có thể truy cập điều này trong đoạn mã phía sau với android.R.attr.activatedBackgroundIndicator.

Bạn attrcó thể tìm thấy danh sách các thuộc tính Android tại R.attr

  • activatedBackgroundIndicator là một phần mềm có thể kéo được xác định trong Android 3.0+ như

    Có thể vẽ được sử dụng làm nền cho các mục đã kích hoạt.

Về cơ bản nó chỉ là một mục tiêu chuẩn được xác định trong Hệ điều hành. Tôi dường như không thể tìm thấy trong nguồn Android, nhưng đây là một liên kết đến tài liệu. activeBackgroundIndicator


5

Đây là một hình thức gắn giá trị từ một chủ đề. Về mặt kỹ thuật, giá trị không được biết trong quá trình biên dịch tài nguyên vì các giá trị chủ đề có thể không được biết tại thời điểm đó. Thay vào đó, giá trị được giải quyết trong thời gian chạy dựa trên chủ đề thực tế được lấy từ (phổ biến nhất) ContextThemeWrapper.

Điều này cung cấp một cách sử dụng lại các giá trị tài nguyên. Tôi không nói về hiệu suất ở đây, mà là tổ chức và bảo trì khôn ngoan. Thuộc tính hoạt động như một biến với lời hứa rằng nó sẽ giữ một giá trị thực tại thời gian chạy.

Cách tiếp cận này cũng cho phép tùy biến tốt hơn - thay vì mã hóa cứng giá trị của ví dụ: nền cửa sổ có thể vẽ được, nó lấy giá trị có thể vẽ thực tế từ một chủ đề, cung cấp một thuộc tính đã chọn làm khóa. Điều này cho phép bạn ghi đè giá trị cho thuộc tính đó. Bạn chỉ cần:

  1. Tạo chủ đề của riêng bạn (chỉ là một cái tên ưa thích cho tài nguyên "phong cách"), phổ biến nhất là bắt nguồn từ một trong các chủ đề mặc định.
  2. Cung cấp giá trị của riêng bạn cho thuộc tính được đề cập.

Nền tảng sẽ tự động sử dụng giá trị của bạn với điều kiện bạn đã chỉ định chủ đề của mình cho một hoạt động hoặc ứng dụng. Bạn làm điều này như mô tả trong câu hỏi. Cú pháp chung của các tham chiếu thuộc tính chủ đề được mô tả ở đây: Tham chiếu các thuộc tính kiểu . Bạn cũng sẽ tìm thấy một ví dụ và mô tả về toàn bộ cơ chế ở đó.

Biên tập

Một điều cần lưu ý là tên thuộc tính thực tế và sự tồn tại của chúng trong các phiên bản nền tảng khác nhau. Việc các thuộc tính mới được giới thiệu trong các phiên bản nền tảng tiếp theo là khá phổ biến - ví dụ như một số thuộc tính đã được thêm vào trong phiên bản 3.0 nhằm mục đích tạo kiểu ActionBar.

Bạn nên coi tên thuộc tính là một phần của API - nói cách khác, chúng là một phần của hợp đồng mà bạn được phép sử dụng. Điều này rất giống với các lớp và chữ ký của chúng - bạn sử dụng LocationManagerlớp với mục đích lấy vị trí thiết bị cuối cùng vì bạn biết từ một số nguồn (hướng dẫn, tài liệu tham khảo, hướng dẫn chính thức, v.v.) mục đích của lớp này là gì. Tương tự, tên thuộc tính và mục đích của chúng (đôi khi tốt, đôi khi sai) được xác định trong tài liệu Nền tảng Android.


2

Cập nhật: Có một phiên bản chi tiết hơn có sẵn từ Hướng dẫn API nên tôi muốn trích dẫn nó.

Tài nguyên thuộc tính kiểu cho phép bạn tham chiếu giá trị của một thuộc tính trong chủ đề hiện đang được áp dụng. Tham chiếu thuộc tính kiểu cho phép bạn tùy chỉnh giao diện của các phần tử giao diện người dùng bằng cách tạo kiểu cho chúng để phù hợp với các biến thể tiêu chuẩn được cung cấp bởi chủ đề hiện tại, thay vì cung cấp một giá trị được mã hóa cứng. Tham chiếu đến một thuộc tính kiểu về cơ bản cho biết, "sử dụng kiểu được xác định bởi thuộc tính này, trong chủ đề hiện tại".

Để tham chiếu thuộc tính style, cú pháp tên gần giống với định dạng tài nguyên thông thường, nhưng thay vì ký hiệu at (@), hãy sử dụng dấu chấm hỏi (?) Và phần loại tài nguyên là tùy chọn. Ví dụ:

Câu trả lời gốc:

numan salati đã đưa ra một câu trả lời hoàn hảo nhưng nó chưa giải quyết được dấu "?" cú pháp. Đây là trích dẫn từ Tài nguyên truy cập Hướng dẫn API

Để tham chiếu thuộc tính style, cú pháp tên gần giống với định dạng tài nguyên thông thường, nhưng thay vì ký hiệu at (@), hãy sử dụng dấu chấm hỏi (?) Và phần loại tài nguyên là tùy chọn. Ví dụ:

? [<package_name>:] [<resource_type> /] <resource_name>

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.