2014-11-3Android学习------关于R.styleable的问题(一)API学习--------GIF动画实现

写一篇文章很辛苦啊!!!

转载请注明,联系请邮件nlp30508@qq.com

这节主要学习下   R.styleable   这个一般出现在定义的attrs.xml文件中,

命名方式是:<declare-styleable name="YourName">

在Android官网的api中说这个一般用在  Creating a View Class时候使用  具体在:Define Custom Attributes

地址为:http://developer.android.com/training/custom-views/create-view.html

1.创建一个试图 Creating a View Class  (也就是自定义自己的视图)

A well-designed custom view is much like any other well-designed class. It encapsulates a specific set of functionality with an easy to use interface, it uses CPU and memory efficiently, and so forth. In addition to being a well-designed class, though, a custom view should:

  • Conform to Android standards
  • Provide custom styleable attributes that work with Android XML layouts
  • Send accessibility events
  • Be compatible with multiple Android platforms.

The Android framework provides a set of base classes and XML tags to help you create a view that meets all of these requirements. This lesson discusses how to use the Android framework to create the core functionality of a view class.

官网首先给出了这一段话:就我理解翻译下

一个设计非常好的自定义视图在很大程度上(或者说非常)像其他任何任何设计良好的类。它封装了一组特定的函数(功能更合适)和易于使用的界面,它利用了CPU和内存效率等等特点。要想做到一个设计非常好的自定义类必须做到以下几点:

1.符号Android标准

2.提供自定义样式属性,它必须能在Android XML布局中有效(就我理解,就是它是符号Android XML定义的,不会出现变异错误)

3.发送可以访问的事务【翻译的不知道正不正确,目前还是初学,请谅解】

4.兼容

2.SubClass a View

接下来,就是先要自定义一个视图,这个视图肯定是继承android.view.View的:

All of the view classes defined in the Android framework extend View. Your custom view can also extend Viewdirectly, or you can save time by extending one of the existing view subclasses, such as Button.

To allow the Android Developer Tools to interact with your view, at a minimum you must provide a constructor that takes a Context and an AttributeSet object as parameters. This constructor allows the layout editor to create and edit an instance of your view.

在Android框架中的任何一个视图类都是继承View(android.view.View),自定义视图也可以直接继承一个视图,你可以通过继承一个已经存在的子视图来节约你的时间,例如:Button

[注意:基本上每一个widget都可以看做是一个视图(与UI有关的构件)]

要允许Android开发工具能够与的视图进行交互,你至少必须提供一个构造函数,这个构造函数带两个参数:

一个是上下文Context,一个是属性集AttributeSet.这个构造函数允许布局编辑器去创建和编辑你自定义视图的一个实例对象。

code:

class PieChart extends View {
    public PieChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

3.Define Custom Attributes

这里算是正式跟标题撤上关系

To add a built-in View to your user interface, you specify it in an XML element and control its appearance and behavior with element attributes. Well-written custom views can also be added and styled via XML. To enable this behavior in your custom view, you must:

  • Define custom attributes for your view in a <declare-styleable> resource element
  • Specify values for the attributes in your XML layout
  • Retrieve attribute values at runtime
  • Apply the retrieved attribute values to your view

在你的应用程序用户界面上添加一个内置的视图,你可以通过一个XML元素去指定它。这个XML元素使用元素属性控制这个视图的外观和行为。精心设计的视图可以通过XML文件添加和样例化。(总之一句话,你可以使用XML文件来定义自己定义的视图的外观和行为),要做到这样,你必须做到以下几点:

1.在XML资源文件中通过<declare-styleabel>这个标签去为你的视图定义自定义属性

2.在XML布局文件中指定属性的值

3.在运行时获取这个属性值

4.将这个属性值应用到你的视图中

To define custom attributes, add <declare-styleable> resources to your project. It's customary to put these resources into a res/values/attrs.xml file. Here's an example of an attrs.xml file:

<resources>
   <declare-styleable name="PieChart">
       <attr name="showText" format="boolean" />
       <attr name="labelPosition" format="enum">
           <enum name="left" value="0"/>
           <enum name="right" value="1"/>
       </attr>
   </declare-styleable>
</resources>

我们需要关心的是这行: <declare-styleable name="PieChart">  属性name=PieChart,这个将作为你用的时候的一个前缀  这里先给出实例:R.styleable.PieChart_showText

This code declares two custom attributes, showText and labelPosition, that belong to a styleable entity named PieChart

上面的代码定义了两个自定义属性,showText 和labelPosition,他们属于styleable类型的一个名叫PieChart实体类的两个属性。

The name of the styleable entity is, by convention, the same name as the name of the class that defines the custom view. Although it's not strictly necessary to follow this convention, many popular code editors depend on this naming convention to provide statement completion.

这里告诉我们,一般我们去定义自己的视图类的时候,类名最好使用 <declare-styleable name="PieChart">中name的定义的名字,与它保持一致。当然它也不是绝对必要的。

Once you define the custom attributes, you can use them in layout XML files just like built-in attributes. The only difference is that your custom attributes belong to a different namespace. Instead of belonging to the http://schemas.android.com/apk/res/android namespace, they belong tohttp://schemas.android.com/apk/res/[your package name]. For example, here's how to use the attributes defined for PieChart:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:custom="http://schemas.android.com/apk/res/com.example.customviews">
 <com.example.customviews.charting.PieChart
     custom:showText="true"
     custom:labelPosition="left" />
</LinearLayout>

一旦你定义好了自定义的属性的时候,你就可以在布局XML文件中使用它们,把他们当做一个内置的属性。

唯一的不同点就是:你自定义的属性属于不同的命名空间,而不是属于Android给出的默认命名空间 如下:

"http://schemas.android.com/apk/res/android"

自定义的属性命名空间属于:

"http://schemas.android.com/apk/res/[your package name]"

上面的代码就是给出的例子:怎么去使用类PieChart视图内作为一个布局文件的内置属性的。

这里还有必要讲一个东西:

xmlns:custom=  这里的custom是可以你自己定义的,想写什么就写什么

然后根据这个custom:showText去取出你定义的那个属性,

它类似与那个xmlns:android=,然后想要获取控件高度的时候就调用android:layout_height="fill_parent"

4.Apply Custom Attributes

When a view is created from an XML layout, all of the attributes in the XML tag are read from the resource bundle and passed into the view's constructor as an AttributeSet. Although it's possible to read values from the AttributeSet directly, doing so has some disadvantages:

  • Resource references within attribute values are not resolved
  • Styles are not applied

Instead, pass the AttributeSet to obtainStyledAttributes(). This method passes back a TypedArray array of values that have already been dereferenced and styled.

当一个视图是从一个XML布局中创建的,所有的XML标记的属性从资源包读取并传递到视图的构造函数为AttributeSet参数中。尽管可以从AttributeSet中直接读取属性值,但是这样做是有一些下面的一些缺点:  1.带值的资源引用是无法办到的 2.样式没有被应用的 相反这样做,通过AttributeSet中的方法obtainStyledAttributes()。此方法通过回调到一个TypeArray类型的数组,这个数组的值已经被解除引用和样例化了。

The Android resource compiler does a lot of work for you to make calling obtainStyledAttributes()easier. For each <declare-styleable> resource in the res directory, the generated R.java defines both an array of attribute ids and a set of constants that define the index for each attribute in the array. You use the predefined constants to read the attributes from the TypedArray.

Android资源编译器做了很多的工作,使得调用obtainStyledAttributes()方法更容易,对任何一个含有

<declare-styleable>标签的资源文件,在自动生成的R.java文件中都定义了两个东西:

一个是属性id数组,一个是一系列常量,该常量是属性数组的下标组成的。

你可以使用这些预定义的常量去从TypeArray类型的数组中读取你定义的属性

 Here's how the PieChart class reads its attributes:

public PieChart(Context context, AttributeSet attrs) {
   super(context, attrs);
   TypedArray a = context.getTheme().obtainStyledAttributes(
        attrs,
        R.styleable.PieChart,
        0, 0);

   try {
       mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
       mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
   } finally {
       a.recycle();
   }
}

Note that TypedArray objects are a shared resource and must be recycled after use.

注意,TypedArray对象是一个共享的资源,并在使用后必须回收。

上面的代码中非常重要地方:

1.构造:super(context,attrs)  这个很重要,有时候我们从source-> generate constructor superclass 发现有三个构造函数,我们要这知道这个就是利用XML做的构造

	// construct - refer for java
	public TypegifView(Context context) {
		this(context, null);
	}

	// construct - refer for xml
	public TypegifView(Context context, AttributeSet attrs) {
		super(context, attrs);
}

2.

   TypedArray a = context.getTheme().obtainStyledAttributes(
        attrs,
        R.styleable.PieChart,
        0, 0);

这行代码非常重要,你是怎么拿出哪些属性的  还有第二种写法:

		TypedArray ta = context.obtainStyledAttributes(attrs,
				R.styleable.PieChart);

上面两种写法都没有问题的。

5.Add Properties and Events

Attributes are a powerful way of controlling the behavior and appearance of views, but they can only be read when the view is initialized. To provide dynamic behavior, expose a property getter and setter pair for each custom attribute. The following snippet shows how PieChart exposes a property called showText: 属性是控制一个视图的外观和行为的有效方法,但是他们只能在视图初始化的时候被读取。

如何提供动态行为,让每个属性(给我们)暴露出set()和get()方法呢,下面的代码给出了例子:

public boolean isShowText() {
   return mShowText;
}

public void setShowText(boolean showText) {
   mShowText = showText;
   invalidate();
   requestLayout();
}

Notice that setShowText calls invalidate() and requestLayout(). These calls are crucial to ensure that the view behaves reliably. You have to invalidate the view after any change to its properties that might change its appearance, so that the system knows that it needs to be redrawn. Likewise, you need to request a new layout if a property changes that might affect the size or shape of the view. Forgetting these method calls can cause hard-to-find bugs.

1.调用invalidate()方法就是当你重新设置 了属性之后,你需要去更新视图的,这个方法被UI线程调用的,由于当前我们的类是直接继承View类的,所以可以直接调用了。

2.同样的,你也需要去调用requestLayout(),因为当你重新设置了属性之后,视图的大小和形状可以发生了改变,也需要去更新视图的。

如果你忘记了这个两个方法,带来的风险就是:很难找到bugs出现在哪里

Events  就是当你触摸视图的时候,发现的事务处理,这个也很容易实现:

步骤如下:

1.在你的自定义视图中,定义一个接口,接口里放你想要做的事务处理,

2.在activity类中去new 这个类中的接口,就可以重写这个函数,当然是在某一个点击事件函数的参数中,例如

btn.setOnClickListoner(new [你自己定以后的接口])

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券