码迷,mamicode.com
首页 > 其他好文 > 详细

自定义控件

时间:2016-05-26 23:21:46      阅读:330      评论:0      收藏:0      [点我收藏+]

标签:

 
技术分享
 
  1. Extend an existing View class or subclass with your own class.
  2. Override some of the methods from the superclass. The superclass methods to override start with ‘on‘, for example, onDraw(), onMeasure(), and onKeyDown(). This is similar to the on... events in Activity or ListActivity that you override for lifecycle and other functionality hooks.
  3. Use your new extension class. Once completed, your new extension class can be used in place of the view upon which it was based.
自定义控件:
继承View
继承已有组件 :继承控件自定义:先查看原有View(类)的已有属性
compound组件(混合)
 
简单自定义控件例子
     当开发者打算派生自己的UI组件时,首先定义一个继承View基类的子类,然后重写View类的一个或多个方法,通常可以被用户重写的方法如下:
构造器:重写构造器是定制View的最基本方式,当Java代码创建一个View实例,根据XML布局文件加载并构建界面时将需要调用该构造器。
-onFinishInflate():这是一个回调方法,当应用从XML布局文件加载该组件并利用它来构建界面之后,该方法就会被回调。
-onMeasure(intint)调用该方法来检测View组件及它所包含的所有子组件的大小。
-onLayout(boolean,int,int,int,int):当该组件需要分配其子组件的位置、大小时,该方法就会被回调。
-onSizeChanged(int,int,int,int)当该组件的大小被改变时回调该方法。
-onDraw(Canvas)当该组件将要绘制它的内容时回调该方法进行绘制。
-onKeyDown(int,KeyEvent):当某个键被按下时触发该方法
-onKeyUp(int,KeyEvent)当松开某个键触发该方法。
-onTrackballEvent(MotionEvent)当发生轨迹球事件时触发该方法。
-onTouchEvent(MotionEvent)  当发生触摸屏事件时触发该方法。
-onWindowFocusChanged(boolean)当该组件得到、失去焦点时触发该方法。
-onAttachedToWindow()当把该组件放入某个窗口时触发该方法。
-onDetachedFromWindow()当把该组件从某个窗口上分离时触发该方法。
-onWindowVisibilityChanged(int)当包含该组件的窗口的可见性发生改变时触发该方法。
实例:跟随手指的小球
publicclassDrawView extends View
{
    publicfloat currentX =40;
    publicfloat currentY =50;
    // 定义、并创建画笔
    Paint p =newPaint();
 
    publicDrawView(Context context)
    {
        super(context);
    }
    publicDrawView(Context context ,AttributeSetset)
    {
        super(context,set);
    }
 
    @Override
    publicvoid onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        // 设置画笔的颜色
        p.setColor(Color.RED);
        // 绘制一个小圆(作为小球)
        canvas.drawCircle(currentX, currentY,15, p);
    }
 
    // 为该组件的触碰事件重写事件处理方法
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // 修改currentX、currentY两个属性
        currentX = event.getX();
        currentY = event.getY();
       // 通知当前组件重绘自己
        invalidate();
        // 返回true表明该处理方法已经处理该事件
        returntrue;
    }
}
 

 
 
自定义控件属性
/res/values/attr/
 第一步:attrs.xml文件
    <?xml version="1.0" encoding="utf-8"?> 
    <resources> 
 
            <attrname="test1"format="string"/>   
 
        <declare-styleablename="MyView"> 
                  <attrname="textColor"format="color"/>   
                  <attrname="textSize"format="dimension"/>   
                  <attrname="text"format="string"/> 
         </declare-styleable>   
    </resources>  
 
  • attr子元素:  
  • 定义具体的属性,format表示这个属性的值的类型,类型有以下几种:  
  •      1.reference:参考指定Theme中资源ID,这个类型意思就是你传的值可以是引用资源  
  •      2.string:字符串,如果你想别人既能直接写值也可以用类似"@string/test"引用资源的方式,可以写成format="string|reference"  
  •      3.Color:颜色  
  •      4.boolean:布尔值  
  •      5.dimension:尺寸值  
  •      6.float:浮点型  
  •      7.integer:整型  
  •      8.fraction:百分数  
  •      9.enum:枚举 ,如果你提供的属性只能让别人选择,不能随便传入,就可以写成这样  
  •         <attr name="language">  
  •                 <enum name="china" value="1"/>  
  •                 <enum name="English" value="2"/>  
  •             </attr>  
  •      10.flag:位或运算  
  • declare-styleable子元素:   
  • 定义一个styleable对象,每个styleable对象就是一组attr属性的集合 注意:这里的name属性并不是一定要和自定义类名相同,只是为了好区分对应类的属性而已  
  •  
  • 注意:上面的属性资源文件定义了该属性之后,至于到底是哪个自定义View组件中来使用该属性,该属性到底能发挥什么作用, 就不归该属性资源文件管了,也就是说这个属性资源文件是个公共的,大家都可以用,但是为了方便管理,一般都是一个自定义View里的属性写成一个declare-styleable集合.属性资源所定义的属性到底可以返回什么作用,取决于自定义组件的代码实现  
第二步:在自定义类里引用attrs文件里定义的属性为自己的属性设置值
 publicclassMyViewextendsView 
 { 
         privatePaint mPaint;   
         privateContext mContext;   
         privatestaticString mString; 
         privateString test; 
 
        publicMyView(Context context)  
        {   
              super(context);   
                mPaint =newPaint();   
        }   
 
        publicMyView(Context context,AttributeSet attrs)   
        {   
                super(context,attrs);   
                mPaint =newPaint();   
 
                    /*这里取得declare-styleable集合*/ 
                 TypedArray typeArray = context.obtainStyledAttributes(attrs,R.styleable.MyView);    
                     /*这里从集合里取出相对应的属性值,第二参数是如果使用者没用配置该属性时所用的默认值*/ 
                int textColor = typeArray.getColor(R.styleable.MyView_textColor,0XFFFFFFFF);   
                float textSize = typeArray.getDimension(R.styleable.MyView_textSize,36);   
                mString = typeArray.getString(R.styleable.MyView_text); 
                 /*设置自己的类成员变量*/ 
                mPaint.setTextSize(textSize);   
                mPaint.setColor(textColor);   
                /*关闭资源*/ 
                typeArray.recycle();   
        }   
        @Override   
        protectedvoid onDraw(Canvas canvas)  
        {   
             super.onDraw(canvas);   
 
             mPaint.setStyle(Style.FILL);         
             canvas.drawRect(newRect(10,10,90,90), mPaint);         
             mPaint.setColor(Color.BLUE);    
             canvas.drawText(mString,10,110, mPaint);   
        }   
}  
第三步:使用自定义组件,并设置属性
 <?xml version="1.0" encoding="utf-8"?> 
<LinearLayout  
      xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:myandroid="http://schemas.android.com/apk/res-auto"
      android:orientation="vertical"> 
 
    <cn.com.androidtest.ui.MyView 
           android:layout_width="fill_parent"  
           android:layout_height="wrap_content"  
           myandroid:textColor="#ff0000" 
           myandroid:textSize="20px" 
           myandroid:text="http://wujiandong.iteye.com"/> 
</LinearLayout>  
命名空间写法:xmlns:空间名="http://schemas.android.com/apk/res/自定义组件所在包名"
写包名时候也有个要注意的地方:如果你的自定义View所在包类似如下两图,那么包名只能写成最顶层包[cn.com.androidtest],而不能是[cn.com.androidtest.ui] 
技术分享技术分享
 
 
 
 
 
 





自定义控件

标签:

原文地址:http://www.cnblogs.com/Doing-what-I-love/p/5533056.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!