自定义控件的步骤

1.自定义类继承自View或View的子类;

2.重写构造方法

(1)MyView(Context);  // 在代码中new 对象时调用此方法

(2)MyView(Context,AttributeSet);  // 在XML布局文件中声明此View,创建对象时,由系统自动调用

(3)MyView(Context,AttributeSet,int);  // 与方法2用法一样,只是多了一个参数:默认样式

3.重写相关方法,实现我们的需求,一般要重写的方法:

(1)onMeasure(int,int);  // 系统测量控件大小时调用该方法

(2)onLayout(boolean,int,int,int,int);  // 系统为该view 指定位置时调用此方法,子view的位置,自身只有建议权,决定权在父view的手中。一般不需要重写。

(3)onDraw(Canvas);  // 为本view绘制内容时,调用该方法。

为新控件添加自定义属性的步骤:

1.在attrs.xml文件中声明属性,有属性名(name)和格式(format)。如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<resources>
    <!-- 声明属性集的名称 -->
    <declare-styleable name="MyToggleBtn" >
    <!-- 声名一个属性 name是my_background 类型为 引用类型 引用资源ID -->
   <attr
     name="my_background"
      format="reference" />
   <!-- 声名一个属性 name是my_slide_btn 类型为 引用类型 引用资源ID -->
   <attr
     name="my_slide_btn"
      format="reference" />
   <!-- 声名一个属性 name是curr_state 类型为 boolean 类型 -->
  <attr
    name="curr_state"
    format="boolean" />
    </declare-styleable>
   </resources>

2.在布局文件中使用新属性,使用之前必须先声明命名空间,如xmlns:gnnuit=”http://schemas.android.com/apk/res/com.gnnuit.togglebutton”,其中“http://schemas.android.com/apk/res/”为Android固定的格式,“com.gnnuit.togglebutton”为应用程序的包名,与AndroidManifest.xml声明的包名一样。

1
2
3
4
5
6
<com.gnnuit.togglebutton.MyToggleButton
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     gnnuit:curr_state="true"
     gnnuit:my_background="@drawable/switch_background"
     gnnuit:my_slide_btn="@drawable/slide_button" />

3.在自定义View的构造方法中,通过解析AttributeSet对象,获得所需要的属性值。

主要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
   package com.jakewharton.nineoldandroids.sample;
   public class MyToggleButton extends View implements android.view.View.OnClickListener {
 
   private Bitmap backgroundBitmap;// 背景图片
   private Bitmap slideButtonBitmap;// 滑动按钮图片
   private Paint paint;
   private boolean currentState = false;// 当前状态
   private float left_slide;// 滑动按钮的左边界位置
   private float startX, lastX;// 记录滑动按钮滑动时的开始和结束位置
   private boolean isSlide = false;// 记录是否移动滑动按钮
    private float dist;
 
/**
*
* 在布局文件中声明此View,创建时由系统自动调用该构造方法
*
*
*
* @param context
*
* @param attrs
*/
 
   public MyToggleButton(Context context, AttributeSet attrs) {
 
      super(context, attrs);
 
    // 获取自定义属性
 
    currentState = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton","curr_state"false);
    int backgroundResourceId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton","my_background", -1);
 
     if (backgroundResourceId == -1) {
      throw new RuntimeException("请设置背景图片");
      }
 
      backgroundBitmap = BitmapFactory.decodeResource(getResources(),
      backgroundResourceId);
      int slideBtnResourceId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton","my_slide_btn", -1);
      if (slideBtnResourceId == -1) {
       throw new RuntimeException("请设置背景图片");
       }
       slideButtonBitmap = BitmapFactory.decodeResource(getResources(),
       slideBtnResourceId);
       if (currentState) {
         left_slide = backgroundBitmap.getWidth()
        - slideButtonBitmap.getWidth();
       }
        initView();// 初始化
       }
 
       /**
        *
       * 初始化
       */
 
     private void initView() {
     // 初始化图片
       // backgroundBitmap = BitmapFactory.decodeResource(getResources(),
       // R.drawable.switch_background);
       // slideButtonBitmap = BitmapFactory.decodeResource(getResources(),
       // R.drawable.slide_button);
       // 初始化画笔
       paint = new Paint();
       paint.setAntiAlias(true);// 设置抗锯齿
       // 设置点击事件
       setOnClickListener(this);
       }
       @Override
      /**
        * 测量尺寸的回调方法*/
       protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          setMeasuredDimension(backgroundBitmap.getWidth(),
          backgroundBitmap.getHeight());// 设置控件的宽和高,单位是像素
       }
     @Override
    /**
      * 绘制当前View的内容
      */
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         canvas.drawBitmap(backgroundBitmap, 00, paint);
         canvas.drawBitmap(slideButtonBitmap, left_slide, 0, paint);.
     }
      @Override
       public void onClick(View v) {
         if (!isSlide) {
            currentState = !currentState;
            flushState();// 刷新界面
        }
       }
 
    /**
      *
      * 刷新当前状态
      */
 
   private void flushState() {
        if (currentState) {
        left_slide = backgroundBitmap.getWidth()
        slideButtonBitmap.getWidth();
      else {
        left_slide = 0;
      }
        invalidate();
     }
   @Override
  public boolean onTouchEvent(MotionEvent event) {
         super.onTouchEvent(event);
         switch (event.getAction()) {
         case MotionEvent.ACTION_DOWN:
              isSlide = false;
              startX = lastX = event.getX();
         break;
         case MotionEvent.ACTION_MOVE:
              lastX = event.getX();
              dist = lastX - startX;
              if (Math.abs(dist) > 5) {
                    isSlide = true;
                    left_slide += dist;
                    flushShow();
                    startX = event.getX();}
         break;
         case MotionEvent.ACTION_UP:
             if (isSlide) {
             if (left_slide > (backgroundBitmap.getWidth() - slideButtonBitmap.getWidth()) / 2) {
                      left_slide = backgroundBitmap.getWidth()
                       slideButtonBitmap.getWidth();
                       currentState = true;
                      else {
                       left_slide = 0;
                       currentState = false;
                      }
                       flushShow();
                       }
          break;}
                  return true;}
 
                /**
                 * 刷新当前View
                 */
        private void flushShow() {
              int maxLeftSlide = backgroundBitmap.getWidth()
              slideButtonBitmap.getWidth();
             // left_slide的范围为0=<left_slide<=maxLeftSlide
               if (left_slide > maxLeftSlide) {
                  left_slide = maxLeftSlide;
                  currentState = true;
                else if (left_slide < 0) {
                   left_slide = 0;
                   currentState = false;}
                 invalidate();}}

文章转载出自:http://www.it165.net/pro/html/201408/20876.html

 

本文永久地址:http://blog.it985.com/10306.html
本文出自 IT985博客 ,转载时请注明出处及相应链接。

arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()