自定义控件-自定义动画的下来刷新

来源:互联网 发布:江恩矩阵图软件下载 编辑:程序博客网 时间:2024/05/16 18:12

从实际角度来说,引入自定义控件是在开发中非常常使用的技术。
原因有两个
1.一个公司有苹果安卓双端产品,要求产品界面风格同意,那么有的时候在苹果上很容易实现的功能在安卓上是没有的,那么就要自己开发一个控件和苹果统一。安卓大多数的设计确实不如苹果美观。
2.开发中将某些控件组合封装成一个控件,例如把开始时间和结束时间组合的日期选择,就非常的使用。载入汽车导航的右侧,始终有一个指南针动态的调整角度,也是非常实用的。
那么为了更好的完成和用户交互,我们不可避免的制作自定义控件。

一个好的自定义控件应当和Android本身提供的控件一样,封装了一系列的功能以供开发者使用,不仅具有完备的功能,也需要高效的使用内存和CPU。Android本身提供了
一些指标:
1. 应当遵守Android标准的规范(命名,可配置,事件处理等)。
2. 在XML布局中可配置控件的属性。
3. 对交互应当有合适的反馈,比如按下,点击等。
4. 具有兼容性, Android版本很多,应该具有广泛的适用性。

  1. View的子类

View在Android是最基础的几个控件之一, 所有的控件均继承自View,你也可以直接继承View也可以继承其他的控件比如ImageView等。

当然,你至少需要提供一个构造函数,其中Context和AttributeSet作为参数。 举例如下:

class PieChart extends View {      public PieChart(Context context, AttributeSet attrs) {          super(context, attrs);      }  }  
  1. 自定义属性
    一个完美的自定义控件也可以添加xml来配置属性和风格。 要实现这一点,可按照下列步骤来做:
    1) 添加自定义属性到xml文件中
    2) 在xml的中,指定属性的值
    3) 在view中获取xml中的值
    4) 将获取的值应用到view中

下面继续举例说明:
添加 到你的程序中,习惯上一般是放在res/values/attrs.xml文件中,例如:

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

附:Android中自定义属性的格式详解
1. reference:参考某一资源ID。
(1)属性定义:

       <declare-styleable name = "名称">                   <attr name = "background" format = "reference" />            </declare-styleable>
(2)属性使用:         <ImageView                 android:layout_width = "42dip"                 android:layout_height = "42dip"                 android:background = "@drawable/图片ID"                 />

2. color:颜色值。
(1)属性定义

      <declare-styleable name = "名称">                   <attr name = "textColor" format = "color" />            </declare-styleable>
(2)属性使用:
     <TextView                     android:layout_width = "42dip"                     android:layout_height = "42dip"                     android:textColor = "#00FF00"                     />
  1. boolean:布尔值。
    (1)属性定义:
     <declare-styleable name = "名称">                   <attr name = "focusable" format = "boolean" />            </declare-styleable>
(2)属性使用:
      <Button                    android:layout_width = "42dip"                    android:layout_height = "42dip"                    android:focusable = "true"                    />
  1. dimension:尺寸值。
    (1)属性定义:
    <declare-styleable name = "名称">                   <attr name = "layout_width" format = "dimension" />            </declare-styleable>
(2)属性使用:
      <Button                    android:layout_width = "42dip"                    android:layout_height = "42dip"                    />
  1. float:浮点值。
    (1)属性定义:
     <declare-styleable name = "AlphaAnimation">                   <attr name = "fromAlpha" format = "float" />                   <attr name = "toAlpha" format = "float" />            </declare-styleable>
(2)属性使用:
      <alpha                   android:fromAlpha = "1.0"                   android:toAlpha = "0.7"                   />
  1. integer:整型值。
    (1)属性定义:
     <declare-styleable name = "AnimatedRotateDrawable">                   <attr name = "visible" />                   <attr name = "frameDuration" format="integer" />                   <attr name = "framesCount" format="integer" />                   <attr name = "pivotX" />                   <attr name = "pivotY" />                   <attr name = "drawable" />
        </declare-styleable>(2)属性使用:
      <animated-rotate                   xmlns:android = "http://schemas.android.com/apk/res/android"                    android:drawable = "@drawable/图片ID"                    android:pivotX = "50%"                    android:pivotY = "50%"                    android:framesCount = "12"                    android:frameDuration = "100"                   />
  1. string:字符串。
    (1)属性定义:
     <declare-styleable name = "MapView">                   <attr name = "apiKey" format = "string" />            </declare-styleable>
(2)属性使用:
       <com.google.android.maps.MapView                    android:layout_width = "fill_parent"                    android:layout_height = "fill_parent"                    android:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"                    />
  1. fraction:百分数。
    (1)属性定义:
    <declare-styleable name="RotateDrawable">
    <attr name = "visible" />
    <attr name = "fromDegrees" format = "float" />
    <attr name = "toDegrees" format = "float" />
    <attr name = "pivotX" format = "fraction" />
    <attr name = "pivotY" format = "fraction" />
    <attr name = "drawable" />
    </declare-styleable>

    (2)属性使用:
    http://schemas.android.com/apk/res/android”
       android:interpolator = “@anim/动画ID”
    android:fromDegrees = “0”
       android:toDegrees = “360”
    android:pivotX = “200%”
    android:pivotY = “300%”
       android:duration = “5000”
    android:repeatMode = “restart”
    android:repeatCount = “infinite”
    />
  2. enum:枚举值。
    (1)属性定义:
      <declare-styleable name="名称">                   <attr name="orientation">                          <enum name="horizontal" value="0" />                          <enum name="vertical" value="1" />                   </attr>                       </declare-styleable>
(2)属性使用:
       <LinearLayout                    xmlns:android = "http://schemas.android.com/apk/res/android"                    android:orientation = "vertical"                    android:layout_width = "fill_parent"                    android:layout_height = "fill_parent"                    >            </LinearLayout>
  1. flag:位或运算。
    (1)属性定义:
      <declare-styleable name="名称">                    <attr name="windowSoftInputMode">                            <flag name = "stateUnspecified" value = "0" />                            <flag name = "stateUnchanged" value = "1" />                            <flag name = "stateHidden" value = "2" />                            <flag name = "stateAlwaysHidden" value = "3" />                            <flag name = "stateVisible" value = "4" />                            <flag name = "stateAlwaysVisible" value = "5" />                            <flag name = "adjustUnspecified" value = "0x00" />                            <flag name = "adjustResize" value = "0x10" />                            <flag name = "adjustPan" value = "0x20" />                            <flag name = "adjustNothing" value = "0x30" />                     </attr>                     </declare-styleable>
 (2)属性使用:
      <activity                   android:name = ".StyleAndThemeActivity"                   android:label = "@string/app_name"                   android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">                   <intent-filter>                          <action android:name = "android.intent.action.MAIN" />                          <category android:name = "android.intent.category.LAUNCHER" />                   </intent-filter>             </activity>
 注意: **属性定义时可以指定多种类型值。**(1)属性定义:
       <declare-styleable name = "名称">                   <attr name = "background" format = "reference|color" />            </declare-styleable>
(2)属性使用:
    <ImageView                     android:layout_width = "42dip"                     android:layout_height = "42dip"                     android:background = "@drawable/图片ID|#00FF00"                     />

有上面的可以看出,如果我建立一个长方体的控件,那么必然要有整形的高这个属性,这就是自定义属性的作用,这些自定义的属性,是每个空间都可以使用的。

另外自定义属性的前提是自定义属性,那么就要在初始化的时候给予正确的命名空间。
在使用的布局文件中,声明有效的namespace
xmlns:zhy=”http://schemas.android.com/apk/res/com.example.test”
此句分为三个字段第一个是
xmlns声明为命名空间
zhy代表自定义的命名前缀
网址内的内容在res/之后添加的是使用自定义属性的自定义控件的包名

然后在我们自定义的控件里使用自定义属性的属性值.
默认将其封装到构造函数之中。如下代码

public MyView extends View{    public MyView(Context context,AttributeSet attrs)    {        super(context,attrs);        TypedArray a = context.obtainStyledAttributes(attr, R.styleable.myView);//TypedArray是一个数组容器         float textSize = a.getDimension(R.styleable.myView_textSize, 30);//防止在XML文件里没有定义,就加上了默认值30        int textColor = a.getColor(R.styleable.myView_textColor, 0xFFFFFFFF);//同上,这里的属性是:名字_属性名          myPaint.setTextSize(textSize);          myPaint.setColor(textColor);         a.recycle();//我的理解是:返回以前取回的属性,供以后使用。以前取回的可能就是textSize和textColor初始化的那段     }}<com.example.test.MyTextView        android:layout_width="@dimen/dp100"        android:layout_height="@dimen/dp200"        zhy:testAttr="520"        zhy:text="@string/hello_world" />MyTextView(4692): attrName = layout_width , attrVal = @2131165234MyTextView(4692): attrName = layout_height , attrVal = @2131165235MyTextView(4692): attrName = text , attrVal = @2131361809MyTextView(4692): attrName = testAttr , attrVal = 520>>use typedarrayMyTextView(4692): text = Hello world! , textAttr = 520

TypedArray的作用
发现了什么?通过AttributeSet获取的值,如果是引用都变成了@+数字的字符串。你说,这玩意你能看懂么?那么你看看最后一行使用TypedArray获取的值,是不是瞬间明白了什么。

TypedArray其实是用来简化我们的工作的,比如上例,如果布局中的属性的值是引用类型(比如:@dimen/dp100),如果使用AttributeSet去获得最终的像素值,那么需要第一步拿到id,第二步再去解析id。而TypedArray正是帮我们简化了这个过程。

declare-styleable的作用

总所周知,系统提供了一个属性叫做:Android:text,那么我觉得直接使用android:text更nice,这样的话,考虑问题:

如果系统中已经有了语义比较明确的属性,我可以直接使用嘛?
答案是可以的,怎么做呢?
直接在attrs.xml中使用android:text属性。

    <declare-styleable name="test">        **<attr name="android:text" />**        <attr name="testAttr" format="integer" />    </declare-styleable>

注意,这里我们是使用已经定义好的属性,不需要去添加format属性(注意声明和使用的区别,差别就是有没有format)。
然后在类中这么获取:ta.getString(R.styleable.test_android_text);布局文件中直接android:text=”@string/hello_world”即可。

这里提一下,系统中定义的属性,其实和我们自定义属性的方式类似,你可以在sdk/platforms/android-xx/data/res/values该目录下看到系统中定义的属性。然后你可以在系统提供的View(eg:TextView)的构造方法中发现TypedArray获取属性的代码(自己去看一下)。

ok,接下来,我在想,既然declare-styleable这个标签的name都能随便写,这么随意的话,那么考虑问题:

styleable 的含义是什么?可以不写嘛?我自定义属性,我声明属性就好了,为什么一定要写个styleable呢?
其实的确是可以不写的,怎么做呢?

首先删除declare-styleable的标签
那么现在的attrs.xml为:

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="testAttr" format="integer" /></resources>

哟西,so清爽~

OK以上完成了自定义控件,自定义属性的详细解释。

开始解析PulltoRefreshView 下拉刷新控件
心得 第一画一个BaseRefreshView
extends Drawable implements Drawable.Callback, Animatable
进行初始化背景的动画底层。
只要完成回调 和getContext return Layout等操作。

然后让想使用的背景动画进行继承 完成动画的初始值的设定已经对动画的要求,已完成在合适的位置以合适的比例让动画动起来。

1 0
原创粉丝点击