一.自定义View构造方法说明
构造方法1
public MyView(Context context) {
super(context);
}
构造方法2
public MyView(Context context,AttributeSet attrs){
super(context, attrs);
}
构造方法3
public MyView(Context context,AttributeSet attrs,int defStyleAttr){
super(context, attrs, defStyleAttr);
}
构造方法4
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
说明
自定 View 的构造函数的参数最多有四个,不过有四个参数的构造函数只能在 API 21 以上使用,因此四个参数的构造函数先不考虑,不过我们也需要了解这四个参数具体代表什么。
参数1:Context: View 中随处都会用到
参数2:AttributeSet: XML 属性(从 XML inflate 的时候使用)
参数3:int defStyleAttr: 应用到 View 的默认风格(定义在主题中)
参数4:int defStyleRes: 如果没有使用 defStyleAttr,应用到 View 的默认风格
调用
<1> 一个参数的构造方法何时调用:MyView myView=new MyView(this);
<2> 两个参数的构造方法何时调用:xml 中添加一个自定义 View ,并且加了一些布局属性,宽高属性以及 margin 属性,这些属性会存放在第二个构造函数的 AttributeSet 参数里。
<3> 三个参数的构造方法何时调用:有三个参数的构造函数比第二个构造函数多了一个 int 型的值,名字叫 defStyleAttr ,从名称上判断,这是一个关于自定义属性的参数。第三个构造函数不会被系统默认调用,而是需要我们自己去显式调用,比如在第二个构造函数里调用调用第三个函数,并将第三个参数设为0 。defStyleAttr 指定的是在Theme style 定义的一个 attr,它的类型是 reference 主要生效在 obtainStyledAttributes 方法里,obtainStyledAttributes 方法有四个参数,第三个参数是 defStyleAttr ,第四个参数是自己指定的一个 style ,当且仅当 defStyleAttr 为 0 或者在 Theme 中找不到 defStyleAttr 指定的属性时,第四个参数才会生效,这些指的都是默认属性,当在 xml 里面定义的,就以在 xml 文件里指定的为准,所以优先级大概是:xml>style>defStyleAttr>defStyleRes>Theme 指定,当defStyleAttr 为 0 时,就跳过 defStyleAttr 指定的 reference ,所以一般用 0 就能满足一些基本开发。
二.attrs.xml文件详解
1.自定义View步骤
<1> 创建控件的类文件,定义其功能逻辑。一般继承自现有控件或者View。
<2> 在res/values目录下创建attrs.xml文件,用于定义该控件的xml标签属性,方便在使用xml声明该控件时设置参数。
<3> 实现该控件的构造器,在构造器中把xml标签属性与后台代码中的变量相连接。
2.具体Demo
<1> 自定义View类
public class MyButton extends android.support.v7.widget.AppCompatButton {
private int step;
private String steps;
//构造方法1
public MyButton(Context context){
super(context);
}
//构造方法2
public MyButton(Context context, AttributeSet attrs){
super(context, attrs);
init(attrs);
}
//构造方法3
public MyButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
//初始化
private void init(AttributeSet attrs){
if(null!=attrs){
TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.myButton);
step=a.getInt(R.styleable.myButton_step, 0);
steps=a.getString(R.styleable.myButton_steps);
a.recycle();
this.setText(step + ""+steps);
}
}
}
说明
TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.myButton);
step=a.getInt(R.styleable.myButton_step, 0);
steps=a.getString(R.styleable.myButton_steps);
<2> attrs.xml
<resources>
<declare-styleable name="myButton">
<attr name="step" format="integer" />
<attr name="steps" format="string" />
</declare-styleable>
</resources>
<3> 布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myviewssss="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.wjn.sqlitedemo.view.MyButton
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:textColor="#FF0000"
myviewssss:step="100"
myviewssss:steps="字符串"/>
</RelativeLayout>
<4> Activity代码
public class MyViewActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_myview);
}
}
<5> 效果
3.attrs.xml文件详解
<1> reference:参考某一资源ID。
属性定义:
<declare-styleable name = "名称">
<attr name = "background" format = "reference" />
</declare-styleable>
属性使用:
<ImageView
android:layout_width = "42dip"
android:layout_height = "42dip"
XXX:background = "@drawable/图片ID/>
<2> color:颜色值。
属性定义:
<declare-styleable name = "名称">
<attr name = "textColor" format = "color" />
</declare-styleable>
属性使用:
<TextView
android:layout_width = "42dip"
android:layout_height = "42dip"
XXX:textColor = "#00FF00"/>
<3> boolean:布尔值。
属性定义:
<declare-styleable name = "名称">
<attr name = "focusable" format = "boolean" />
</declare-styleable>
属性使用:
<Button
android:layout_width = "42dip"
android:layout_height = "42dip"
XXX:focusable = "true" />
<4> dimension:尺寸值。
属性定义:
<declare-styleable name = "名称">
<attr name = "layout_width" format = "dimension" />
</declare-styleable>
属性使用:
<Button
XXX:layout_width = "42dip"
android:layout_height = "42dip" />
<5> float:浮点值。
属性定义:
<declare-styleable name = "AlphaAnimation">
<attr name = "fromAlpha" format = "float" />
<attr name = "toAlpha" format = "float" />
</declare-styleable>
属性使用:
<alpha
XXX:fromAlpha = "1.0"
XXX:toAlpha = "0.7" />
<6> integer:整型值。
属性定义:
<declare-styleable name = "AnimatedRotateDrawable">
<attr name = "frameDuration" format="integer" />
</declare-styleable>
属性使用:
<animated-rotate
xmlns:android = "http://schemas.android.com/apk/res/android"
XXX:frameDuration = "100" />
<7> string:字符串。
属性定义:
<declare-styleable name = "MapView">
<attr name = "apiKey" format = "string" />
</declare-styleable>
属性使用:
<com.google.android.maps.MapView
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
XXX:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"/>
<8> fraction:百分数。
属性定义:
<declare-styleable name="RotateDrawable">
<attr name = "pivotY" format = "fraction" />
</declare-styleable>
属性使用:
<rotate
xmlns:android = "http://schemas.android.com/apk/res/android"
XXX:pivotY = "300%" />
<9> enum:枚举值。
属性定义
<declare-styleable name="名称">
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
</declare-styleable>
属性使用:
<LinearLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent">
</LinearLayout>
<10> flag:位或运算。
属性定义:
<declare-styleable name="名称">
<attr name="windowSoftInputMode">
<flag name = "stateUnspecified" value = "0" />
<flag name = "stateUnchanged" value = "1" />
<flag name = "adjustNothing" value = "0x30" />
</attr>
</declare-styleable>
属性使用:
<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>
注意:
属性定义时可以指定多种类型值。
属性定义:
<declare-styleable name = "名称">
<attr name = "background" format = "reference|color" />
</declare-styleable>
属性使用:
<ImageView
android:layout_width = "42dip"
android:layout_height = "42dip"
android:background = "@drawable/图片ID|#00FF00" />
附:View重要的回调方法
1.onFinishInflate():在此控件被通过xml声明的方式创建之后调用。
2.onMeasure(in,int):计算本控件的宽高,如果继承自原有控件,则一般不需要重写此方法。
3.onLayout():用于布局控件,对于不是继承ViewGroup的控件,一般不需要重写此方法。
4.onDraw():在绘制控件时候调用,控件具体长什么样子就在此方法中实现。