【问题标题】:Help with a custom View attributes inside a Android Library Project帮助在 Android 库项目中自定义视图属性
【发布时间】:2010-12-16 13:49:40
【问题描述】:

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

package com.mysite.android.library.pietimer;

public class PieTimerView extends View {
...

我还有一个在我的 PieTimer 中使用的 XML 属性文件

    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 显示,但属性不起作用,它们使用默认值(以前没有发生过),因此这里发生了一些命名空间冲突。

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

【问题讨论】:

  • 您找到更好的解决方案了吗?
  • 请告诉我有更好的方法来做到这一点。我在图书馆项目中包含 admob 广告时遇到了同样的问题。
  • 好问题。我也面临同样的问题。欢迎大家提出意见。
  • @SIVAKUMAR.J - JRaymond 对此给出了正确答案(在我撰写此评论时,这是该问题的最高评分。)

标签: android


【解决方案1】:

我知道这篇文章太老了,但是如果有人来看的话,这个问题已经在 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 拍的不错,原文链接在这里:Revisions for ADT 17.0.0
  • 问题:我们的构建目标是什么重要吗? (我猜不是,但我不太确定......)
  • @ArtOfWarfare 不应该,这是工具集的一部分,它会调整您的来源。应该只关心您安装了什么版本的工具
【解决方案2】:

与我的同事一起工作了两个小时后,我们弄清楚了如何完成这项工作:

库:com.library

mywidget.java 带有一个类MyWidget

attrs.xml:

    <declare-styleable name="MyWidget">

并把你的属性。

不用在布局(例如 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>

应用: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】:

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

    【讨论】:

      【解决方案4】:

      对于所有 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>
      

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

      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)是一个错误的地方。您可以在 AndroidMinifest.xml 文件中查看 minifest 元素的 package 属性。它们应该是相同的。

        【讨论】:

        • 不完全相同,因为这是一个库项目(包含所有逻辑和布局),子项目具有不同的命名空间,这导致了问题。像这样,com.mysite.android.library.myapp.litecom.mysite.android.library.myapp.upgrade
        • 我确实通过手动将所有布局文件复制到子项目并更改命名空间来解决这个问题......但这是一个非常讨厌的解决方案,尤其是当您有多个布局时。
        【解决方案6】:

        这个解决方案对我有用:

        https://gist.github.com/1105281

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

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

        但是,您应该为 Lint 声明相同的属性名称样式,以免在编写 XML 部分时显示错误。

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-27
          • 2013-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-24
          相关资源
          最近更新 更多