1.基础一:坐标计算

1.1 Android窗口坐标系计算以屏幕左上角为原点,

向右为X轴正向,向下为Y轴正向

1.2 View坐标系

【注意获取的坐标是像素值,不是dp值】
【注意获取的坐标是像素值,不是dp值】
【注意获取的坐标是像素值,不是dp值】

//获取View内部相对的坐标值(距离)getX()getY()//获取View相对父View的相对坐标值(距离)getLeft()getTop()getRight()getBottom()//获取的是屏幕中的实际坐标值(距离)getRawX()getRawY()

图中activity指全屏窗口,严格的讲应该是屏幕

1.3 实际开发使用场景

1.获取View的宽高【应在View绘制完成后调用

width = getRight() - getLeft();height = getBottom() - getTop();

2.获取View在父view中的左上角坐标【应在View绘制完成后调用

Point point = new Point();point.set(ivState.getLeft() ,ivState.getTop());

3.获取View在父view中心点坐标【应在View绘制完成后调用

Point point = new Point();point.set(ivState.getRight() - ivState.getLeft() ,ivState.getBottom() - ivState.getTop());

2. 自定义属性

2.1 构造函数&初始化属性

public class MDButton extends Button {         //java动态创建view时调用    public MDButton(Context context) {             super(context);        initInnerView(context);    }    //xml布局初始化时调用    public MDButton(Context context, AttributeSet attrs) {             super(context, attrs);//        initInnerView(context);//组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用        initAttrs(context, attrs);    }    //有默认style时,在MDButton(Context context, AttributeSet attrs)中调用MDButton(context,attrs,defStyleAttr);    public MDButton(Context context, AttributeSet attrs, int defStyleAttr) {             super(context, attrs, defStyleAttr);//        initInnerView(context);//组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用        initAttrs(context, attrs);    }    //只有在API版本>21时才会用到    //有默认style时,在MDButton(Context context, AttributeSet attrs)中调用MDButton(context,attrs,defStyleAttr);    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    public MDButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {             super(context, attrs, defStyleAttr, defStyleRes);//        initInnerView(context);//组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用        initAttrs(context, attrs);    }    //组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用    private void initInnerView(Context context) {             //...    }    private void initAttrs(Context context, AttributeSet attrs) {             //...    }}

2.2 自定义属性

1.在module中的/res/values/attrs.xml编写属性&类型;

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="MDButton">                <attr name="mdb_bg" format="color|reference" />        <attr name="mdb_txt_color" format="color|reference" />                <attr name="mdb_txt" format="string" />                <attr name="mdb_auto_anim" format="boolean" />                <attr name="mdb_anim_pivotX" format="fraction" />                <attr name="mdb_auto_anim_delay" format="integer" />                <attr name="mdb_auto_anim_alpha" format="float" />                <attr name="mdb_min_width" format="dimension" />                <attr name="mdb_size">            <enum name="small" value="0" />            <enum name="normal" value="1" />            <enum name="big" value="2" />        attr>                <attr name="mdb_radius_corner">            <flag name="empty" value="0x00" />            <flag name="top" value="0x01" />            <flag name="bottom" value="0x02" />            <flag name="left" value="0x04" />            <flag name="right" value="0x08" />        attr>    declare-styleable>resources>

2.自定义View类中获取属性值,并使用

public class MDButton extends Button {         //组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用    private void initInnerView(Context context) {             //...    }    private void initAttrs(Context context, AttributeSet attrs) {             //1.获取属性数组        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MDButton);               //2.获取属性值        Drawable bgDrawable = typedArray.getDrawable(R.styleable.MDButton_mdb_bg);        int txtColor = typedArray.getInteger(R.styleable.MDButton_mdb_txt_color,Color.parseColor("#808080"));        String txt = typedArray.getString(R.styleable.MDButton_mdb_txt);        boolean isAutoAnim = typedArray.getBoolean(R.styleable.MDButton_mdb_auto_anim, false);        float fraction = typedArray.getFraction(R.styleable.MDButton_mdb_anim_pivotX, 1, 1, 1.0f);        float alpha = typedArray.getFloat(R.styleable.MDButton_mdb_auto_anim_alpha , 1.0f);        float minWidth = typedArray.getDimension(R.styleable.MDButton_mdb_min_width, 32.0f);        int sizeType = typedArray.getInt(R.styleable.MDButton_mdb_size, 1);//0=small 1=normal 2=big        int radiusCorner = typedArray.getInt(R.styleable.MDButton_mdb_radius_corner ,0);        int delay = typedArray.getInt(R.styleable.MDButton_mdb_auto_anim_delay ,0);        Log.e("bgDrawable",""+bgDrawable);        Log.e("txtColor",""+txtColor);        Log.e("txt",""+txt);        Log.e("isAutoAnim",""+isAutoAnim);        Log.e("fraction",""+fraction);        Log.e("alpha",""+alpha);        Log.e("minWidth",""+minWidth);        Log.e("sizeType",""+sizeType);        Log.e("radiusCorner",""+radiusCorner);        Log.e("delay",""+delay);        Log.e("==============","=========================================");                //3.属性值 设置到 对应属性        setText(txt);        //tv.setDelay(delay);        //...                //4.释放        typedArray.recycle();    }    //java动态创建view时调用    public MDButton(Context context) {             super(context);        initInnerView(context);    }    //xml布局初始化时调用    public MDButton(Context context, AttributeSet attrs) {             super(context, attrs);//        initInnerView(context);//组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用        initAttrs(context, attrs);    }    //有默认style时,在MDButton(Context context, AttributeSet attrs)中调用MDButton(context,attrs,defStyleAttr);    public MDButton(Context context, AttributeSet attrs, int defStyleAttr) {             super(context, attrs, defStyleAttr);//        initInnerView(context);//组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用        initAttrs(context, attrs);    }    //只有在API版本>21时才会用到    //有默认style时,在MDButton(Context context, AttributeSet attrs)中调用    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    public MDButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {             super(context, attrs, defStyleAttr, defStyleRes);//        initInnerView(context);//组合式自定义View(即ViewGroup)时,需初始化内部子view; 扩展式自定义View不需要调用        initAttrs(context, attrs);    }}

3.在布局文件.xml中使用控件,【注意变量组设置的数据&单位】

 <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        app:layout_constraintTop_toTopOf="parent"        app:layout_constraintLeft_toLeftOf="parent"        android:orientation="vertical"        >        <com.cupster.base_super_resource.MDButton            app:mdb_anim_pivotX="80%"            app:mdb_auto_anim="true"            app:mdb_auto_anim_alpha="1.0"            app:mdb_auto_anim_delay="100"            app:mdb_bg="@drawable/shape_btn_gray_radius5"            app:mdb_min_width="60dp"            app:mdb_radius_corner="right"            app:mdb_size="big"            app:mdb_txt="btn1"            app:mdb_txt_color="#ff00ff"            android:layout_width="120dp"            android:layout_height="60dp"            />        <com.cupster.base_super_resource.MDButton            app:mdb_anim_pivotX="70%"            app:mdb_auto_anim="false"            app:mdb_auto_anim_alpha="0.4"            app:mdb_auto_anim_delay="100"            app:mdb_bg="@drawable/shape_btn_gray_radius5"            app:mdb_min_width="60px"            app:mdb_radius_corner="bottom|left|top|right"            app:mdb_size="small"            app:mdb_txt="btn1"            app:mdb_txt_color="#ff00ff"            android:layout_width="120dp"            android:layout_height="60dp"            />        <com.cupster.base_super_resource.MDButton            app:mdb_anim_pivotX="100%"            app:mdb_auto_anim_alpha="0.9"            app:mdb_auto_anim_delay="100"            app:mdb_bg="@drawable/shape_btn_gray_radius5"            app:mdb_min_width="90dp"            app:mdb_radius_corner="empty"            app:mdb_size="normal"            app:mdb_txt="btn1"            app:mdb_txt_color="#ff00ff"            android:layout_width="120dp"            android:layout_height="60dp"            />    LinearLayout>

** 附 :属性值获取正确性验证**

3.自定义View分类

3.1 组合式

顾名思义,即xml文件中根布局使用RelativeLayout(同理其他布局控件),
内部使用其他View控件,布局摆放,组合成XxxView的原始布局。
然后,Java类继承根布局标签对应的容器类,覆写构造函数,并初始化各子View的变量。
是最常用、最稳妥、不易产生过度绘制、内存泄漏等问题。

Android自定义View(1):组合式

3.2 继承覆写

简而言之,即 如继承Button,修改默认background、state_press状态时按钮elevation值、取消默认最小高度56dp等。
也是最常用的、直接扩展/修改原生View功能

Android自定义View(2):继承改写

3.3 自绘式

强烈建议:熟悉View的绘制、Android事件传递、手势处理再入手自绘式。

方式:直接继承View ,重写绘制流程三步骤

  1. measure() 测量
  2. layout() 布局计算摆放坐标
  3. draw() 绘制

Android自定义View(3):自绘式

更多相关文章

  1. 调用Android原生裁剪方式裁剪图片并保存
  2. Android调用系统相册和相机选择图片并显示在imageview中
  3. 关于android双卡手机sim卡信息采集适配的心得
  4. Android相机、相册获取图片,解决相机拍照图片被压缩模糊的情况
  5. BroadcastReceiver与Notification的综合应用之自定义Action的调
  6. Android(安卓)Studio精彩案例(三)《模仿微信ViewPage+Fragment实
  7. Android上hook AMS和PMS
  8. Android获取数据时 浮点型整数位数值(超8位)过大导致科学计数法
  9. android相机如何只显示处理后的图像以及这里onPreviewFrame不被

随机推荐

  1. mysql limit 分页的用法及注意要点
  2. mysql limit分页优化详细介绍
  3. MySQL数据库 1067错误号的解决方法
  4. MySQL数据库基础命令大全(收藏)
  5. centos7安装mysql并jdbc测试教程
  6. 理解MySQL——索引与优化总结
  7. Mysql 忘记root密码的完美解决方法
  8. 详解mysql 获取当前日期及格式化
  9. MariaDB 新版本实力逆袭不仅仅是 MySQL
  10. 详解MySQL中concat函数的用法(连接字符串)