Помощь с настраиваемыми атрибутами 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

Он определенно проигрывает копирование файлов и изменение пространств имен, но он по-прежнему не такой элегантный, как должен быть. Наслаждайтесь.