自定义View 基础知识

一.自定义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():在绘制控件时候调用,控件具体长什么样子就在此方法中实现。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值