下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 人教版六年级下册数学期末测试卷及1套参考答案
- 人教版六年级下册数学期末测试卷及答案参考
- 人教版六年级下册数学期末测试卷含完整答案(必刷)
- 人教版六年级下册数学期末测试卷(考点精练)
- 人教版四年级下册数学期末测试卷【学生专用】
- 人教版四年级下册数学期末测试卷及答案【考点梳理】
- 人教版四年级下册数学期末测试卷附答案【b卷】
- 小学六年级下册数学期末测试卷【考试直接用】
- 小学六年级下册数学期末测试卷含答案(夺分金卷)
- 小学六年级下册数学期末测试卷附答案(完整版)
- 小班安全教育《走丢了怎么办》
- 城市更新的方法及策略-以长春市新民大街为例
- 理解性默写汇编 统编版高中语文必修下册
- 中国高血压防治指南 2023版
- 星巴克人力资源管理案例分析
- 六年级下册综合实践活动导学案-小龙虾的秘密 全国通用
- 《如何进行亲子沟通》教案
- 提高住院病历完成及时性持续改进(PDCA)
- 2023年广州一模读后续写jobos+on+the+hill+讲义 高考英语作文复习专项
- 滨州市惠民县2022-2023学年数学五下期末统考试题含答案
- 湖南省2023年普通高中学业水平考试合格性考试(专家B卷)高二政治试题
评论
0/150
提交评论