帮助Android库项目中的自定义视图属性

时间:2010-12-16 13:49:40

标签: android

我在Android库项目中有自定义的PieTimer视图

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等属性的命名空间,但是当我将项目作为一个库项目并且有一个实现该库的Free和Full版本时,我发现它不再有效所以我添加了pie命名空间。

PieTimerView显示但是属性不起作用,它们使用默认值(之前没有发生过),因此这里存在一些名称空间冲突。

这样做的正确方法是什么?

6 个答案:

答案 0 :(得分:92)

我知道这篇文章超级老了,但如果有人来看,这个问题已在ADT修订版17+中得到修复。任何服务或活动都将名称空间声明为:

xmlns:custom="http://schemas.android.com/apk/res-auto"

res-auto将在构建时被实际项目包替换,因此请确保设置属性名称以避免发生冲突。

参考: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/

答案 1 :(得分:9)

在与同事一起工作两个小时后,我们想出了如何做到这一点:

图书馆:com.library

mywidget.java,类MyWidget

attrs.xml:

    <declare-styleable name="MyWidget">

然后把你的attr。

不要在其中声明窗口小部件的布局(例如main.xml),只需在库的布局文件夹中创建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>

将其包含在您的布局中,只需输入

即可
<include layout="@layout/my_widget"></include>

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

通常它会起作用!

答案 2 :(得分:4)

这里有一个已知的错误及其描述:bug #9656。我还在我的博客post中描述了为什么会这样。

答案 3 :(得分:1)

对于所有API,这是收据(如果库链接为JAR ,但也应该作为android库项目引用)

图书馆计划: 的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(或您使用自定义控件的布局)

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

在应用程序代码中,如果要从库使用中访问资源(例如,来自lib的arrays.xml中定义的数组“MyCustomArray”),请使用:

getResources().getStringArray(com.myapp.library1.R.array.MyCustomArray)

答案 4 :(得分:0)

xmlns:app="http://schemas.android.com/apk/res/com.mysite.android.library.myapp"

您指定的包(com.mysite.android.library.myapp)可能是错误的地方。您可以在AndroidMinifest.xml文件中检查minifest元素的package属性。它们应该完全相同。

答案 5 :(得分:0)

这个解决方案对我有用:

https://gist.github.com/1105281

它不使用TypedArray并要求视图在其中硬编码库的项目包名称。

它也不使用程序化级别的可设置值。您还必须将属性字符串硬编码到视图中。

但是,您应该声明Lint的相同属性名称,以便在编写XML部件时不显示错误。

指向code.google.com上原始帖子的链接:

http://code.google.com/p/android/issues/detail?id=9656#c17

它绝对胜过复制文件和更改命名空间,但它仍然没有那么优雅。享受。