Android自定义View(一)关于super、this和构造方法

其实我发现个问题,我写的博客都是我边学变写的,当回过头来再看之前的博客,感觉总是:这特么写的什么玩意了!所以,感谢你能看我的博客,虽然有点糟糕。


        进入主题,先说this关键字。

        这个关键字用的还是挺多的:Activity中的Context对象、实现的接口、冲突命名时指定成员变量;实体类中setter方法指定成员变量;指代不同参的构造方法;

  1. public class ThisClass {  
  2.     private int number;  
  3.     public ThisClass() {  
  4.         this(1);//指向其他的不同参构造器  
  5.     }  
  6.     public ThisClass(int number) {  
  7.         this.number = number;//名字冲突后区分成员变量  
  8.     }  
  9.     public void setNumber(int number) {  
  10.         this.number = number;//名字冲突后区分成员变量  
  11.     }  
  12. }  
public class ThisClass {
    private int number;
    public ThisClass() {
        this(1);//指向其他的不同参构造器
    }
    public ThisClass(int number) {
        this.number = number;//名字冲突后区分成员变量
    }
    public void setNumber(int number) {
        this.number = number;//名字冲突后区分成员变量
    }
}

        总的来说:this是指向对象本身的指针。有一点要注意:匿名内部类中的this指向的是匿名类。

 

        接下来是super:

        super存在于有继承关系的子类里;super相当于father.this;”super(xxx)”可以访问到父类中同参的father(xxx)构造方法;”super.xxx()”可以访问到父类中的xxx()方法;

 

  1. public class SuperClass extends ThisClass {  
  2.     public SuperClass() {  
  3.         super();//指向父类的ThisClass()构造方法  
  4.     }  
  5.     public SuperClass(int a) {  
  6.         super(a);//指向父类的ThisClass(int number)构造方法  
  7.     }  
  8.     public int getInt(){  
  9. //        return super.getNumber();//调用父类ThisClass的getNumber()方法  
  10.         return this.getNumber();//调用自己的getNumber()方法;this.可以省略  
  11.     }  
  12.     public int getNumber(){  
  13.         return 1;  
  14.     }  
  15. }  
public class SuperClass extends ThisClass {
    public SuperClass() {
        super();//指向父类的ThisClass()构造方法
    }
    public SuperClass(int a) {
        super(a);//指向父类的ThisClass(int number)构造方法
    }
    public int getInt(){
//        return super.getNumber();//调用父类ThisClass的getNumber()方法
        return this.getNumber();//调用自己的getNumber()方法;this.可以省略
    }
    public int getNumber(){
        return 1;
    }
}

 

        Super必须写在构造方法的第一行,这是龟腚,我也没有深究是为什么。

 

        说完了this和super,该说和View相关的了。

        自定义view,通常的顺序是先extendView,然后必须实现一个默认的构造方法,可选的有三个(API21以后是四个,通常建议都实现),实例如下:

  1. public class MyView extends View {  
  2.     public MyView(Context context) {  
  3.         super(context);  
  4.     }  
  5.     public MyView(Context context, AttributeSet attrs) {  
  6.         super(context, attrs);  
  7.     }  
  8.     public MyView(Context context, AttributeSet attrs, int defStyleAttr) {  
  9.         super(context, attrs, defStyleAttr);  
  10.     }  
  11. }  
public class MyView extends View {
    public MyView(Context context) {
        super(context);
    }
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}


        这里我们可以看到每个方法都有一个super,如果去掉这行代码,就会报错。要说清楚到底都是怎么个意思,是很困难的,我们不如去看一下View类中的这几个方法之间的关联,先说明一下View类有22K多行代码,这里只截取我们感兴趣的:

  1. @UiThread  
  2. public class View implements Drawable.Callback, KeyEvent.Callback,  
  3.         AccessibilityEventSource {  
  4.     public View(Context context) {  
  5.         mContext = context;  
  6.         //省略了一堆代码  
  7.     }  
  8.     public View(Context context, @Nullable AttributeSet attrs) {  
  9.         this(context, attrs, 0);  
  10.     }  
  11.     public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {  
  12.         this(context, attrs, defStyleAttr, 0);  
  13.     }  
  14.     public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {  
  15.         this(context);  
  16.         //省略了近500行代码      
  17. }  
@UiThread
public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
    public View(Context context) {
        mContext = context;
        //省略了一堆代码
    }
    public View(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }
    public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        this(context);
		//省略了近500行代码    
}



        我们可以看到:两个参数的添加参数后调用了三个参数的,三个参数的添加了默认值又调用了四个参数的(这个是API21+),而四个参数的第一行却是调用一个参数的。


         我们可以做一个大概的猜测:只提供一个Context参数的构造方法是核心方法,而其他的都是点缀的意义,最终的最终还是要执行这里。

         看到这里也不知道看官有没有明白我想说的意思,或者有没有什么想法?有疑问也是好的啊!

         起码应该有一个疑问,BB这么多,什么时候怎么用呢?

         1.在代码中直接new一个Custom View实例的时候,会调用第一个构造函数.这个没有任何争议.

         2.在xml布局文件中调用CustomView的时候,会调用第二个构造函数.这个也没有争议.

         3.在xml布局文件中调用CustomView,并且Custom View标签中还有自定义属性时,这里调用的还是第二个构造函数.

         4.其实我也不知道

         多参就是为了处理参数,然后才是正儿八经的实现控件。

        

        第一部分我想说得就到这了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值