【移动应用开发技术】怎么在Android中实现一个水滴效果_第1页
【移动应用开发技术】怎么在Android中实现一个水滴效果_第2页
【移动应用开发技术】怎么在Android中实现一个水滴效果_第3页
【移动应用开发技术】怎么在Android中实现一个水滴效果_第4页
【移动应用开发技术】怎么在Android中实现一个水滴效果_第5页
免费预览已结束,剩余2页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】怎么在Android中实现一个水滴效果

这期内容当中在下将会给大家带来有关怎么在Android中实现一个水滴效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。一、总体思路1、画两个圆形,其中一个就是上面的大圆,还有一个是下面的小圆,大圆和小圆不断变小,大圆的位置保持不变,小圆的位置不断向下移动,即圆心不断下移。2、画两边的曲线,这时候用到贝塞尔曲线去画。3、用属性动画实现动态的效果。二、代码实现1、找出画曲线的几个关键点。其实我是在第一张图的基础上,再在上面分别画两个圆,就可以得到第二张图了。关键是画出第一张图。(1)在这里,p1,p2,p3,p4,这4个点分别对应两个圆的两边的点,即p1到p2就是圆的直径。p3和p4同理,那么就很容易确定这四个点的坐标了。(2)然后c1和c2是分别控制p1到p3、p2到p4的曲线,是贝塞尔曲线的控制点。它们的横坐标对应的是p3,p4的横坐标(相等),纵坐标取两个圆心距离的一半。这样画出这个静态的图片就不难了。(3)画上下两个圆进去,就会变成第二张图的效果。2、在构造方法中调用init()初始化一些基本的变量private

void

init(Context

context,

AttributeSet

attrs)

{

drawFilter

=

new

PaintFlagsDrawFilter(0,

Paint.ANTI_ALIAS_FLAG

|

Paint.FILTER_BITMAP_FLAG);

paint

=

new

Paint();

paint.setColor(fillColor);

//

转换为像素单位

bigRadius

=

dip2px(context,

bigRadius);

smallRadius

=

dip2px(context,

smallRadius);

distance

=

dip2px(context,

distance);

}3、在onDraw()方法中画水滴效果要注意的是path需要重新new,贝塞尔曲线的绘制,用到是path.quadTo这方法。具体可以看代码。@Override

protected

void

onDraw(Canvas

canvas)

{

//

必须重新new,不然路径会重复,我之前就是这样

path

=

new

Path();

//

把画布移到中心

canvas.translate(width

/

2,

height

/

2);

//

从canvas层面去除绘制时锯齿

canvas.setDrawFilter(drawFilter);

//

当前的两个圆心的距离

currentDis

=

distance

*

fraction;

//

计算当前大圆的半径

float

bigRadius

=

this.bigRadius

-

currentDis

/

bigPercent;

float

smallRadius

=

0;

if

(currentDis

>

5)

{//

距离大于5才改变小圆的半径

smallRadius

=

this.smallRadius

-

currentDis

/

smallPercent;

}

//

大圆两边的两个点坐标

leftX

=

-bigRadius;//

大圆当前的半径

leftY

=

rightY

=

0;

rightX

=

bigRadius;//

大圆当前的半径

//

小圆两边的两个点坐标

leftX2

=

-smallRadius;//

小圆当前的半径

leftY2

=

rightY2

=

currentDis;

rightX2

=

-leftX2;

//

小圆当前的半径

//

两个控制点

controlX1

=

-smallRadius;//

x坐标取小圆当前的半径大小

controlY1

=

currentDis

/

2;//

y坐标取两个圆距离的一半

controlX2

=

smallRadius;//

x坐标取小圆当前的半径大小

controlY2

=

currentDis

/

2;//

y坐标取两个圆距离的一半

path.moveTo(leftX,

leftY);

path.lineTo(rightX,

rightY);

//

用二阶贝塞尔曲线画右边的曲线,参数的第一个点是右边的一个控制点

path.quadTo(controlX2,

controlY2,

rightX2,

rightY2);

path.lineTo(leftX2,

leftY2);

//

用二阶贝塞尔曲线画左边边的曲线,参数的第一个点是左边的一个控制点

path.quadTo(controlX1,

controlY1,

leftX,

leftY);

//

画大圆

canvas.drawCircle(0,

0,

bigRadius,

paint);

//

画小圆

canvas.drawCircle(0,

currentDis,

smallRadius,

paint);

//

画path

canvas.drawPath(path,

paint);

}4、用属性动画,实现动态的效果。/***

执行属性动画,实现水滴的效果

*/

public

void

perforAnim()

{

ValueAnimator

valAnimator

=

ObjectAnimator.ofFloat(0,

1);

valAnimator.addUpdateListener(new

AnimatorUpdateListener()

{

@Override

public

void

onAnimationUpdate(ValueAnimator

animation)

{

fraction

=

(float)

animation.getAnimatedValue();

postInvalidate();

}

});

valAnimator.setDuration(duration);

valAnimator.start();

}5、重写onMeasure()方法,处理wrap_content情况。@Override

protected

void

onMeasure(int

widthMeasureSpec,

int

heightMeasureSpec)

{

super.onMeasure(widthMeasureSpec,

heightMeasureSpec);

/*

*

处理为wrap_content情况,那么它的specMode是AT_MOST模式,在这种模式下它的宽/高

*

等于spectSize,这种情况下view的spectSize是parentSize,而parentSize是

*

父容器目前可以使用大小,就是父容器当前剩余的空间大小,

就相当于使用match_parent一样

的效果,因此我们可以设置一个默认的值

*/

int

widthSpectMode

=

MeasureSpec.getMode(widthMeasureSpec);

int

widthSpectSize

=

MeasureSpec.getSize(widthMeasureSpec);

int

heightSpectMode

=

MeasureSpec.getMode(heightMeasureSpec);

int

heightSpectSize

=

MeasureSpec.getSize(heightMeasureSpec);

if

(widthSpectMode

==

MeasureSpec.AT_MOST

&&

heightSpectMode

==

MeasureSpec.AT_MOST)

{

setMeasuredDimension(width,

height);

}

else

if

(widthSpectMode

==

MeasureSpec.AT_MOST)

{

setMeasuredDimension(width,

heightSpectSize);

}

else

if

(heightSpectMode

==

MeasureSpec.AT_MOST)

{

setMeasuredDimension(widthSpectSize,

height);

}

}6、其它的一些方法实现。@Override

protected

void

onLayout(boolean

changed,

int

left,

int

top,

int

right,

int

bottom)

{

super.onLayout(changed,

left,

top,

right,

bottom);

if

(changed)

{

width

=

right

-

left;

height

=

bottom

-

top;

}

}

/**

*

根据手机的分辨率从

dp

的单位

转成为

px(像素)

*/

public

int

dip2px(Context

context,

float

dpValue)

{

final

float

scale

=

context.getResources().getDisplayMetrics().density;

return

(int)

(dpValue

*

scale

+

0.5f);

}7、字段的定义private

final

int

fillColor

=

0xff999999;//

填充颜色

private

Paint

paint;

private

int

width

=

100,

height

=

300;//

默认宽高

/*

两个圆心的最大距离

/

private

int

distance

=

60;

/*

当前两个圆心的距离

/

private

float

currentDis

=

0;

private

float

bigRadius

=

20;//

大圆半径

private

float

smallRadius

=

10;//

小圆半径

private

float

controlX1,

controlX2,

controlY1,

controlY2;//

两个控制点的坐标

private

float

leftX,

leftY,

rightX,

rightY;//

大圆两边的两个点的坐标

private

float

leftX2,

leftY2,

rightX2,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论