zoukankan      html  css  js  c++  java
  • xml中控件调用构造方法

    系统控件view有三个构造方法,分别如下

    public DrawView(Context context) {
            super(context);
            
        }
    
        public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            
        }
    
        public DrawView(Context context, AttributeSet attrs) {
            super(context, attrs);
            
        }

    关于构造方法,网上给的解释是

    如果在Code中实例化一个View会调用第一个构造函数,如果在xml中定义会调用第二个构造函数,而第三个函数系统是不调用的,要由 View(我们自定义的或系统预定义的View,如此处的CustomTextView和Button)显式调用,比如在这里我们在第二个构造函数中调用 了第三个构造函数,并将R.attr.CustomizeStyle传给了第三个参数。第三个参数的意义就如同它的名字所说的,是默认的Style,只是这里没有说清楚,这里的默认的Style是指它在当前Application或Activity所用的Theme中的默认Style。

    至于只有一个参数的方法,我们主要是在new一个view的时候,会使用。它的那个参数是上下文环境。如

    Button button = new Button(this);

    至于两个参数跟三个参数的方法调用情况,网上有说是跟你在xml中是否使用了style有关。不过,我验证了下,无论有无style,都仅仅是调用两个参数的构造方法。验证如下

    自定义style

    package com.example.testcode;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    
    public class DrawView extends View {
    
        public DrawView(Context context) {
            super(context);
            
        }
    
        public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            
        }
    
        public DrawView(Context context, AttributeSet attrs) {
            super(context, attrs);
            
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // TODO Auto-generated method stub
            
            //这两个方法必须有一个,否则会报错
            //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(200, 200);
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right,
                int bottom) {
            // TODO Auto-generated method stub
            Log.e("123", "change===" + changed + " left===" + left + " top==="
                    + top + " right===" + right + " bottom===" + bottom);
            super.onLayout(changed, left, top, right, bottom);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            Log.e("123", "onDraw");
            super.onDraw(canvas);
        }
    }

    xml中的使用

    1.当没有style的时候

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.testcode.MainActivity" >
    
        <com.example.testcode.DrawView
            android:layout_width="100dp"
            android:layout_height="100dp"
            />
    
    </RelativeLayout>

    打印结果

    09-29 11:28:13.445: E/123(6555): drawview_2

    2.当有style的时候

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.testcode.MainActivity" >
    
        <com.example.testcode.DrawView
            style="@style/test"
            />
    
    </RelativeLayout>

    style

    <style name="test">
            <item name="android:layout_width">100dp</item>
            <item name="android:layout_height">100dp</item>
            <item name="android:background">#ff0000</item>
        </style>


    打印结果

    09-29 11:28:13.445: E/123(6555): drawview_2

    所以,xml中的控件,只调用两个参数的方法。而三个参数的方法,其实是在二个参数的方法中显式调用的。我们可以看下Button源码

    public class Button extends TextView {
        public Button(Context context) {
            this(context, null);
        }   
    
        public Button(Context context, AttributeSet attrs) {
            this(context, attrs, com.android.internal.R.attr.buttonStyle);
        }   
    
        public Button(Context context, AttributeSet attrs, int defStyleAttr) {
            this(context, attrs, defStyleAttr, 0); 
        }   
    
        public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }   
    
        @Override
        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
            super.onInitializeAccessibilityEvent(event);
            event.setClassName(Button.class.getName());
        }   
    
        @Override
        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(info);
            info.setClassName(Button.class.getName());
        }   
    }

    从上面我们很清除的看到了这几个构造方法的调用关系

    1.1参数->2参数(没有传入属性)->3参数(传入了系统默认的style)->4参数

  • 相关阅读:
    第一章 基础知识
    第1条:考虑用静态工厂方法代替构造器
    spring cloud(断路器——初学五)
    spring cloud(断路器——初学四)
    spring cloud(服务消费者(利用feign实现服务消费及负载均衡)——初学三)
    在阿里云的ubuntu服务器上安装xampp时出现unable to realloc unable to realloc 8380000 bytes错误
    laravel中ubuntu下执行php artisan migrate总是报错
    windows下安装php依赖关系管理工具composer
    apk下载的网址生成一个二维码
    android apk的签名和权限问题
  • 原文地址:https://www.cnblogs.com/zhangshuli-1989/p/vz_constructor_15910161.html
Copyright © 2011-2022 走看看