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

从实际角度来说,引入自定义控件是在开发中非常常使用的技术。
原因有两个
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 = @2131165234
MyTextView(4692): attrName = layout_height , attrVal = @2131165235
MyTextView(4692): attrName = text , attrVal = @2131361809
MyTextView(4692): attrName = testAttr , attrVal = 520
>>use typedarray
MyTextView(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值