programacion - Ayuda con un atributo de vista personalizado dentro de un proyecto de biblioteca de Android
manual de programacion android pdf (6)
Después de dos horas de trabajo con mi compañero de trabajo, descubrimos cómo hacer que esto funcione: Biblioteca: com.library mywidget.java con una clase MyWidget
attrs.xml:
<declare-styleable name="MyWidget">
y pon tu atributo
En lugar de tener su diseño (main.xml, por ejemplo) con su widget declarado en él, juste cree un my_widget.xml en el escritorio de su biblioteca. 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>
para incluirlo en su diseño, juste poner
<include layout="@layout/my_widget"></include>
Aplicación: com.myapp
Debe juste duplicar my_widget.xml aquí y cambiar el espacio de nombres:
<?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>
¡Y normalmente funcionará!
Tengo una vista PieTimer personalizada en un proyecto de biblioteca de Android
package com.mysite.android.library.pietimer;
public class PieTimerView extends View {
...
También tengo un archivo de atributos XML que utilizo en mi PieTimer
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.PieTimerView);
El archivo de estilo XML se ve así
<?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>
Tengo el PieTimer en un archivo de diseño para un proyecto que usa la biblioteca, como este
<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>
Anteriormente estaba usando la xmlns:app
como espacio de nombres para atributos como app:ok_color
pero cuando hice que mi proyecto fuera un proyecto de biblioteca y tuviera una versión gratuita y completa implementando la biblioteca, descubrí que ya no funcionaba, así que agregué el espacio de nombres circular.
El PieTimerView muestra pero los atributos no funcionan, usan el valor predeterminado (esto no ocurría antes) por lo que hay algún conflicto de espacio de nombres aquí.
¿Cuál es la forma correcta de hacer esto?
Esta solución funcionó para mí:
https://gist.github.com/1105281
No utiliza el TypedArray y requiere que la vista tenga el nombre del paquete del proyecto de la biblioteca codificado en él.
Tampoco usa los valores estiloables en el nivel programático. También debe codificar las cadenas de atributos en la vista.
Sin embargo, debe declarar que los mismos nombres de atributo son editables para que Lint no muestre un error al escribir la parte XML.
Un enlace a la publicación original en code.google.com:
http://code.google.com/p/android/issues/detail?id=9656#c17
Definitivamente es mejor copiar los archivos y cambiar los espacios de nombres, pero todavía no es tan elegante como debería ser. Disfrutar.
Hay un error conocido y se describe aquí: bug # 9656 . También describí por qué sucede esto en mi publicación de blog.
Para todas las API, este es el recibo ( si la biblioteca está vinculada como JAR , pero debería funcionar también como referencia del proyecto de la biblioteca de Android)
Proyecto de biblioteca: AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.library1"
...
</manifest>
Proyecto de biblioteca: Attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustStyle" >
<attr name="MyAttr1" format="dimension" />
..
</resources>
Proyecto de aplicación MainLayout.xml (o el diseño donde usa el control personalizado)
<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>
En el código de la aplicación, si desea acceder a los recursos del uso de la biblioteca (por ejemplo, array "MyCustomArray" definido en arrays.xml fromthe lib) use:
getResources().getStringArray(com.myapp.library1.R.array.MyCustomArray)
Sé que esta publicación es muy antigua, pero si alguien viene a buscar, este problema se ha solucionado en la revisión 17+ de ADT. Cualquier servicio o actividad declara el espacio de nombre como:
xmlns:custom="http://schemas.android.com/apk/res-auto"
res-auto se reemplazará en el momento de la compilación con el paquete de proyecto real, por lo que debe asegurarse de configurar sus nombres de atributo para evitar colisiones, si es posible.
xmlns:app="http://schemas.android.com/apk/res/com.mysite.android.library.myapp"
tal vez el paquete (com.mysite.android.library.myapp) que especificó es un lugar incorrecto. Puede verificar el atributo de paquete del elemento minifest en el archivo AndroidMinifest.xml. deberían ser idénticos.