Android自定义view详解,使用实例,自定义属性,贝塞尔曲线

  • Left:子View左上角距父View左侧的距离;

  • Bottom:子View右下角距父View顶部的距离

  • Right:子View右下角距父View左侧的距离


6. 位置获取方式

==========================================================================

  • View的位置是通过view.getxxx()函数进行获取:(以Top为例)

// 获取Top位置

public final int getTop() {  

    return mTop;  

}  



// 其余如下:

  getLeft();      //获取子View左上角距父View左侧的距离

  getBottom();    //获取子View右下角距父View顶部的距离

  getRight();     //获取子View右下角距父View左侧的距离

  • 与MotionEvent中 get()getRaw()的区别

//get() :触摸点相对于其所在组件坐标系的坐标

 event.getX();       

 event.getY();



//getRaw() :触摸点相对于屏幕默认坐标系的坐标

 event.getRawX();    

 event.getRawY();



具体如下图:

get() 和 getRaw() 的区别

7. Android的角度(angle)与弧度(radian)

================================================================================================

  • 自定义View实际上是将一些简单的形状通过计算,从而组合到一起形成的效果。

    这会涉及到画布的相关操作(旋转)、正余弦函数计算等,即会涉及到角度(angle)与弧度(radian)的相关知识。

  • 角度和弧度都是描述角的一种度量单位,区别如下图::

角度和弧度区别

在默认的屏幕坐标系中角度增大方向为顺时针。

屏幕坐标系角度增大方向

注:在常见的数学坐标系中角度增大方向为逆时针


8. Android中颜色相关内容

==================================================================================

Android中的颜色相关内容包括颜色模式,创建颜色的方式,以及颜色的混合模式等。

8.1 颜色模式

Android支持的颜色模式:

Android颜色模式

以ARGB8888为例介绍颜色定义:

ARGB88888

8.2 定义颜色的方式

8.2.1 在java中定义颜色


 //java中使用Color类定义颜色

 int color = Color.GRAY;     //灰色



  //Color类是使用ARGB值进行表示

  int color = Color.argb(127, 255, 0, 0);   //半透明红色

  int color = 0xaaff0000;                   //带有透明度的红色

8.2.2 在xml文件中定义颜色

在/res/values/color.xml 文件中如下定义:


<?xml version="1.0" encoding="utf-8"?>

<resources>



    //定义了红色(没有alpha(透明)通道)

    <color name="red">#ff0000</color>

    //定义了蓝色(没有alpha(透明)通道)

    <color name="green">#00ff00</color>

</resources>



在xml文件中以”#“开头定义颜色,后面跟十六进制的值,有如下几种定义方式:


  #f00            //低精度 - 不带透明通道红色

  #af00           //低精度 - 带透明通道红色



  #ff0000         //高精度 - 不带透明通道红色

  #aaff0000       //高精度 - 带透明通道红色

8.3 引用颜色的方式

8.3.1 在java文件中引用xml中定义的颜色:


//方法1

int color = getResources().getColor(R.color.mycolor);



//方法2(API 23及以上)

int color = getColor(R.color.myColor);    

8.3.2 在xml文件(layout或style)中引用或者创建颜色


 <!--在style文件中引用-->

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

        <item name="colorPrimary">@color/red</item>

    </style>



 <!--在layout文件中引用在/res/values/color.xml中定义的颜色-->

  android:background="@color/red"     



 <!--在layout文件中创建并使用颜色-->

  android:background="#ff0000"        

--------------------- 作者:Carson_Ho 来源:CSDN 原文:https://blog.csdn.net/carson_ho/article/details/56009827?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

使用实例:

=====

1、Android自定义View构造函数详解

public DragBallView(Context context) {

this(context, null);

LgqLogutil.e(“1”);

}

public DragBallView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 1);

LgqLogutil.e(“2”);

}

public DragBallView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initPaint();

initPoint();

}

new引用,调用第一个构造函数

DragBallView dragBallView = new DragBallView(this);

xml文件引用调用第二个构造函数

<com.tianxin.ttttest.DragBallView

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:id=“@+id/mydrag”/>

第三个可在第二个函数调用之

2、单位转换

/**

* dp 2 px图片

*

* @param dpVal

*/

protected int dp2px(int dpVal) {

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,

dpVal, getResources().getDisplayMetrics());

}

/**

* sp 2 px文字

*

* @param spVal

* @return

*/

protected int sp2px(int spVal) {

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,

spVal, getResources().getDisplayMetrics());

}

3、判断触摸点是否在View范围之内

//是否可拖拽

private boolean mIsCanDrag = false;

/**

* 判断是否可以拖拽

*

* @param event event

*/

private void setIsCanDrag(MotionEvent event) {

Rect rect = new Rect();

rect.left = (int) (startX - radiusStart);

rect.top = (int) (startY - radiusStart);

rect.right = (int) (startX + radiusStart);

rect.bottom = (int) (startY + radiusStart);

//触摸点是否在圆的坐标域内

mIsCanDrag = rect.contains((int) event.getX(), (int) event.getY());

}

@Override

public boolean onTouchEvent(MotionEvent event) {

float currentX;

float currentY;

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

setIsCanDrag(event);

4、实时刷新onDraw方法

invalidate();

5、实现构造函数方法以及onSizeChanged方法和onDraw方法即可实现自定义View

onSizeChanged初始化数据

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

startX = w / 2;

startY = h / 2;

onDraw方法实现

(1)绘制背景。由private方法drawBackground()完成。如果未设定背景Drawable对象,则会直接返回。

(2)绘制内容。由onDraw()方法完成。

(3)绘制子视图。由dispatchView()完成。View的dispatchView()是空方法,ViewGroup的dispatchView()有具体实现,主要是调用子视图的draw()方法。

(4)绘制装饰。主要是foreground与滚动条。

因此,只要最高层的根布局调用了它的draw()方法,低层的所有view的draw()方法最终都会被调用。因此,大部分情况下draw()方法是不需要手动调用的,我们只需要覆盖onDraw()方法,将自己的内容绘制出来即可。

画圆

canvas.drawCircle(pointF.x, pointF.y, radius, circlePaint);

cx:圆心的x坐标。

cy:圆心的y坐标。

radius:圆的半径。

paint:绘制时所使用的画笔

画框:

mPaint.setStrokeWidth((float) 3.0);              //线宽

mPaint.setStyle(Paint.Style.STROKE);                   //空心效果

画线


canvas.drawLine(startX, startY, startX, endY, mCenterLinePaint);

虚线


int dp4 = Utils.dp2px(context, 4);

dashLine[0] = dp4;

dashLine[1] = dp4;


    void drawLine(Canvas canvas, float startX, float startY, float length) {

        int index = (int) ((length / (dashLine[0] + dashLine[1]))) + 1;

        float endY = startY;

        for (int i = 0; i < index; i++) {

            endY += dashLine[0];

            canvas.drawLine(startX, startY, startX, endY, mCenterLinePaint);

//            endY += dashLine[1];

            endY += 20;

            startY = endY;

        }

    }

画矩形

canvas.drawRect(textRect,testpaint);

椭圆


private RectF mSeatNoRectF = new RectF();


canvas.drawRoundRect(mSeatNoRectF, mSeatNoTopMargin, mSeatNoTopMargin, mSeatNoPaint);

画字体

canvas.drawText(msgCount > 99 ? “99+” : msgCount + “”, textRect.centerX(),  baseline, textPaint);

画贝塞尔曲线

private void drawBezier(Canvas canvas) {

path.reset();

path.moveTo(pointA.x, pointA.y);

path.quadTo(pointO.x, pointO.y, pointB.x, pointB.y);

path.lineTo(pointC.x, pointC.y);

path.quadTo(pointO.x, pointO.y, pointD.x, pointD.y);

path.lineTo(pointA.x, pointA.y);

path.close();

canvas.drawPath(path, circlePaint);

}

附:

textRect.left = (int) (point.x - radiusStart+15);

textRect.top = (int) (point.y - radiusStart);

textRect.right = (int) (point.x + radiusStart-15);

textRect.bottom = (int) (point.y + radiusStart);

Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();

int baseline = (textRect.bottom + textRect.top - fontMetrics.bottom - fontMetrics.top) / 2;

画满:


mPaint.setStyle(Paint.Style.FILL);

自定义属性

1、values文件夹下创建attrs文件夹


<?xml version="1.0" encoding="utf-8"?>

<resources>

    <declare-styleable name="CircleView">

        <attr name="radius" format="integer"/>

        <attr name="CircleX" format="integer"/>

        <attr name="CircleY" format="integer"/>

        <attr name="age">

            <flag name='child' value="10"/>

            <flag name="young" value="18"/>

            <flag name="old" value="60"/>

        </attr>

    </declare-styleable>

</resources>

2、 自定义view使用自定义属性

3、XML文件调用自定义属性

贝塞尔曲线

======


/\*\*

 \* @author : LGQ

 \* @date : 2020/09/08 15



## 最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套**腾讯、头条、阿里、美团等公司19年的面试题**,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含**知识脉络 + 诸多细节**,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 **高级架构技术进阶脑图、Android开发面试专题资料**,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。


**【Android核心高级技术PDF文档,BAT大厂面试真题解析】**

![](https://img-blog.csdnimg.cn/img_convert/a4d0ef1e40b5bae89a57f6e70ca70843.webp?x-oss-process=image/format,png)

**【算法合集】**

![](https://img-blog.csdnimg.cn/img_convert/9f8a769ee064a70ecd0770924b3ed904.webp?x-oss-process=image/format,png)

**【延伸Android必备知识点】**

![](https://img-blog.csdnimg.cn/img_convert/6fcf75bf5ee1d89869f5559d1c8930a3.webp?x-oss-process=image/format,png)

**【Android部分高级架构视频学习资源】**

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套**腾讯、头条、阿里、美团等公司19年的面试题**,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含**知识脉络 + 诸多细节**,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 **高级架构技术进阶脑图、Android开发面试专题资料**,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。


**【Android核心高级技术PDF文档,BAT大厂面试真题解析】**

[外链图片转存中...(img-PmgZBXam-1725916935863)]

**【算法合集】**

[外链图片转存中...(img-vVJdMoGT-1725916935864)]

**【延伸Android必备知识点】**

[外链图片转存中...(img-jhqboRfE-1725916935864)]

**【Android部分高级架构视频学习资源】**

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值