Помощь с настраиваемыми атрибутами View в проекте библиотеки Android
У меня есть пользовательский PieTimer View в проекте Android Library
package com.mysite.android.library.pietimer;
public class PieTimerView extends View {
...
У меня также есть файл атрибутов XML, который я использую в своем PieTimer
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.PieTimerView);
XML-стильный файл выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PieTimerView">
<attr name="max_size" format="dimension" />
<attr name="start_angle" format="string" />
<attr name="start_arc" format="string" />
<attr name="ok_color" format="color" />
<attr name="warning_color" format="color" />
<attr name="critical_color" format="color" />
<attr name="background_color" format="color" />
</declare-styleable>
</resources>
У меня есть PieTimer в файле макета для проекта, который использует библиотеку, вроде этого
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root" android:layout_gravity="center_horizontal"
xmlns:app="http://schemas.android.com/apk/res/com.mysite.android.library.myapp"
xmlns:pie="com.mysite.library.pietimer"
>
<com.mysite.library.pietimer.PieTimerView
pie:start_angle="270"
pie:start_arc="0"
pie:max_size="70dp"
pie:ok_color="#9798AD"
pie:warning_color="#696DC1"
pie:critical_color="#E75757"
pie:background_color="#D3D6FF"
android:visibility="visible"
android:layout_height="wrap_content" android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_alignParentRight="true">
</com.mysite.library.pietimer.PieTimerView>
Раньше я использовал xmlns:app
в качестве пространства имен для таких атрибутов, как app:ok_color
, но когда я сделал проект проектом библиотеки и имел бесплатную и полную версию библиотеки, я обнаружил, что она больше не работает, поэтому я добавил пространство имен пирога.
Отображается PieTimerView, но атрибут не работает, они используют значение по умолчанию (это не происходило раньше), поэтому здесь существует конфликт конфликтов пространства имен.
Каков правильный способ сделать это?
Ответы
Ответ 1
Я знаю, что этот пост очень стар, но если кто-то придет посмотреть, эта проблема была исправлена в версии 17+ ADT. Любые службы или действия объявляют пространство имен следующим образом:
xmlns:custom="http://schemas.android.com/apk/res-auto"
res-auto будет заменен во время сборки фактическим пакетом проекта, поэтому убедитесь, что вы настроили имена своих атрибутов, чтобы избежать столкновений, если это вообще возможно.
ref: http://www.androidpolice.com/2012/03/21/for-developers-adt-17-sdk-tools-r17-and-support-package-r7-released-with-new-features-and-fixes-for-lint-build-system-and-emulator/
Ответ 2
После двух часов работы с моим коллегой мы выясним, как сделать эту работу:
Библиотека: com.library
mywidget.java с классом MyWidget
attrs.xml:
<declare-styleable name="MyWidget">
и поместите свой attr
Вместо того, чтобы иметь свой макет (например, main.xml) с объявленным в нем виджетами, juste создайте файл my_widget.xml в макете вашей библиотеки.
my_widget.xml
<?xml version="1.0" encoding="utf-8"?>
<com.library.MyWidget
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:widget="http://schemas.android.com/apk/res/com.library"
android:id="@+id/your_id"
android:layout_width="fill_parent" android:layout_height="fill_parent"
widget:your_attr>
</com.library.MyWidget>
для включения его в ваш макет, juste put
<include layout="@layout/my_widget"></include>
Приложение: com.myapp
Вам просто нужно дублировать файл my_widget.xml и изменить пространство имен:
<?xml version="1.0" encoding="utf-8"?>
<com.library.MyWidget
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:widget="http://schemas.android.com/apk/res/com.myapp" <---- VERY IMPORTANT
android:id="@+id/your_id"
android:layout_width="fill_parent" android:layout_height="fill_parent"
widget:your_attr>
</com.library.MyWidget>
И обычно это сработает!
Ответ 3
Известная ошибка и ее описание здесь: ошибка # 9656. Я также описал, почему это происходит в моем блоге post.
Ответ 4
Для всех API-интерфейсов это квитанция (, если библиотека связана как JAR, но должна работать также как ссылка на проект библиотеки андроида)
Проект библиотеки:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.library1"
...
</manifest>
Проект библиотеки:
Attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustStyle" >
<attr name="MyAttr1" format="dimension" />
..
</resources>
Проект приложения
MainLayout.xml(или макет, где u использует настраиваемый элемент управления)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:library1="http://schemas.android.com/apk/com.myapp.library1"
...
>
<com.myapp.library1.MyCustomView
library1:MyAttr1="16dp"
...
/>
</RelativeLayout>
В коде приложения, если вы хотите получить доступ к ресурсам из использования библиотеки (например, массив "MyCustomArray", определенный в файле arrays.xml from lib), используйте:
getResources().getStringArray(com.myapp.library1.R.array.MyCustomArray)
Ответ 5
xmlns:app="http://schemas.android.com/apk/res/com.mysite.android.library.myapp"
Возможно, указанный вами пакет (com.mysite.android.library.myapp) указан неверно. вы можете проверить атрибут package элемента minifest в файле AndroidMinifest.xml. они должны быть идентичными.
Ответ 6
Это решение работало для меня:
https://gist.github.com/1105281
Он не использует TypedArray и требует, чтобы представление содержало в нем имя пакета проекта библиотеки.
Он также не использует значения стиля на программном уровне. Вы также должны жестко закодировать строки атрибутов в представлении.
Однако вы должны объявлять те же самые имена атрибутов, что и Lint, чтобы не показывать ошибку при написании XML-части.
Ссылка на исходное сообщение на code.google.com:
http://code.google.com/p/android/issues/detail?id=9656#c17
Он определенно проигрывает копирование файлов и изменение пространств имен, но он по-прежнему не такой элегантный, как должен быть. Наслаждайтесь.