版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在Android中利用三阶贝塞尔曲线绘制运动轨迹
怎么在Android中利用三阶贝塞尔曲线绘制运动轨迹?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面在下将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。xml布局:<RelativeLayout
xmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:id="@+id/rl_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".touch.MainActivity">
<.touch.MyLoveLayout
android:layout_marginBottom="100dp"
android:layout_marginRight="15dp"
android:id="@+id/love_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</.touch.MyLoveLayout>
<Button
android:id="@+id/bt_bottom"
android:text="begin"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:layout_width="100dp"
android:layout_height="50dp"
/>
</RelativeLayout>MainActivity类:public
class
MainActivity
extends
Activity
implements
View.OnClickListener{
private
Button
btBottom;
//
private
WaitNoticeDialog
dialog;
//
public
Handler
handler;
private
MyLoveLayout
love;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btBottom
=
(Button)
findViewById(R.id.bt_bottom);
love
=
(MyLoveLayout)
findViewById(R.id.love_layout);
btBottom.setOnClickListener(this);
//
handler=new
IHandler(this);
//
dialog
=
new
WaitNoticeDialog(this);
}
static
class
IHandler
extends
Handler
{
private
WeakReference<MainActivity>
ui;
IHandler(MainActivity
ui)
{
this.ui
=
new
WeakReference<MainActivity>(ui);
}
@Override
public
void
handleMessage(Message
msg)
{
if(ui!=null&&ui.get()!=null){
ui.get().handleMsg(msg);
}
}
}
/**
*
线程消息处理
*
@param
msg
*/
public
void
handleMsg(Message
msg){
switch
(msg.what)
{
}
}
@Override
public
void
onClick(View
v)
{
switch
(v.getId()){
case
R.id.bt_bottom:
love.addHeart();
break;
}
}
@Override
protected
void
onDestroy()
{
super.onDestroy();
//
handler.removeCallbacksAndMessages(null);
}
}自定义view:MyLoveLayoutpublic
class
MyLoveLayout
extends
RelativeLayout
{
private
Drawable[]
drawables;
private
Interpolator[]
mInterpolators;
private
int
dWidth,
mWidth;
private
int
dHeight,
mHeight;
private
LayoutParams
lp;
private
Random
random
=
new
Random();
public
MyLoveLayout(Context
context,
AttributeSet
attrs)
{
super(context,
attrs);
//imageView位置是相对于MyLoveLayout
init();
}
@Override
protected
void
onMeasure(int
widthMeasureSpec,
int
heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec,
heightMeasureSpec);
//得到本布局的宽高
mWidth
=
getMeasuredWidth();
mHeight
=
getMeasuredHeight();
}
private
void
init()
{
//
初始化显示的图片
drawables
=
new
Drawable[7];
drawables[0]
=
getResources().getDrawable(R.drawable.heart_1);
drawables[1]
=
getResources().getDrawable(R.drawable.heart_2);
drawables[2]
=
getResources().getDrawable(R.drawable.heart_3);
drawables[3]
=
getResources().getDrawable(R.drawable.heart_4);
drawables[4]
=
getResources().getDrawable(R.drawable.heart_5);
drawables[5]
=
getResources().getDrawable(R.drawable.heart_6);
drawables[6]
=
getResources().getDrawable(R.drawable.heart_7);
//
初始化插补器
mInterpolators
=
new
Interpolator[4];
mInterpolators[0]
=
new
LinearInterpolator();//
线性
mInterpolators[1]
=
new
AccelerateInterpolator();//
加速
mInterpolators[2]
=
new
DecelerateInterpolator();//
减速
mInterpolators[3]
=
new
AccelerateDecelerateInterpolator();//
先加速后减速
//
获取图片宽高
//
dWidth
=
drawables[0].getIntrinsicWidth();
//
dHeight
=
drawables[0].getIntrinsicHeight();
//手动设置宽高
dWidth
=
dip2px(getContext(),
40);
dHeight
=
dip2px(getContext(),
40);
lp
=
new
LayoutParams(dWidth,
dHeight);
//设置view控件的起始位置
//
lp.addRule(CENTER_HORIZONTAL,
TRUE);//
这里的TRUE
要注意
不是true
lp.addRule(ALIGN_PARENT_RIGHT,
TRUE);
lp.addRule(ALIGN_PARENT_BOTTOM,
TRUE);
}
/**
*
dp转px值
*/
private
int
dip2px(Context
context,
float
dpValue)
{
float
scale
=
context.getResources().getDisplayMetrics().density;
return
(int)
(dpValue
*
scale
+
0.5f);
}
/**
*
进场动画,三种同时播放
*
alpha透明度
(80%-0%)
*
scaleX
宽度
target(20%-100%)
*
scaleY
高度
*
@param
target
*
@return
*/
private
AnimatorSet
getEnterAnimator(final
View
target)
{
ObjectAnimator
alpha
=
ObjectAnimator.ofFloat(target,
View.ALPHA,
0.2f,
1f);
ObjectAnimator
scaleX
=
ObjectAnimator.ofFloat(target,
View.SCALE_X,
0.2f,
1f);
ObjectAnimator
scaleY
=
ObjectAnimator.ofFloat(target,
View.SCALE_Y,
0.2f,
1f);
AnimatorSet
enter
=
new
AnimatorSet();
enter.setTarget(target);
enter.setInterpolator(new
LinearInterpolator());
enter.setDuration(500).playTogether(alpha,
scaleX,
scaleY);
return
enter;
}
private
ValueAnimator
getBezierValueAnimator(final
View
target)
{
//
初始化贝塞尔估值器
//随机产生两个点,以确定一条3阶贝塞尔曲线
BezierEvaluator
evaluator
=
new
BezierEvaluator(getPointF(2),
getPointF(1));
//
起点在底部中心位置,终点在底部随机一个位置,改变new
PointF()中值来改变起始位置
//
ValueAnimator
animator
=
ValueAnimator.ofObject(evaluator,
new
PointF((mWidth
-
dWidth)
/
//
2,
mHeight
-
dHeight),
new
PointF(random.nextInt(getWidth()),
0));
//
起点在右下角位置,终点在左上角位置
ValueAnimator
animator
=
ValueAnimator.ofObject(evaluator,
new
PointF(mWidth
-
dWidth,
mHeight
-
dHeight),
new
PointF(0,
0));
animator.setTarget(target);
animator.addUpdateListener(new
ValueAnimator.AnimatorUpdateListener()
{
@Override
public
void
onAnimationUpdate(ValueAnimator
valueAnimator)
{
//
这里获取到贝塞尔曲线计算出来的的x
y值
赋值给view
这样就能让爱心随着曲线走啦
PointF
pointF
=
(PointF)
valueAnimator.getAnimatedValue();
target.setX(pointF.x);
target.setY(pointF.y);
//
alpha动画,根据运动距离改变透明度
//
target.setAlpha(1
-
valueAnimator.getAnimatedFraction());
target.setAlpha(1
-
valueAnimator.getAnimatedFraction()
+
0.3f);
}
});
animator.setDuration(3000);
return
animator;
}
private
PointF
getPointF(int
i)
{
PointF
pointF
=
new
PointF();
//pointF.x,pointF.y都是随机,因此可以产生n多种轨迹
pointF.x
=
random.nextInt(mWidth);//0~loveLayout.Width
//为了美观,建议尽量保证P2在P1上面,那怎么做呢??
//只需要将该布局的高度分为上下两部分,让p1只能在下面部分范围内变化(1/2height~height),让p2只能在上面部分范围内变化(0~1/2height),因为坐标系是倒着的;
//0~loveLayout.Height/2
if
(i
==
1)
{
pointF.y
=
random.nextInt(mHeight
/
2)
+
mHeight
/
2;//P1点Y轴坐标变化
}
else
if
(i
==
2)
{//P2点Y轴坐标变化
pointF.y
=
random.nextInt(mHeight
/
2);
}
//
写死的一条轨迹
//
if
(i
==
1)
{
//
pointF.x=mWidth-dWidth*2;
//
pointF.y
=
3*dHeight;
//
}
else
if
(i
==
2)
{
//
pointF.x=dWidth*2;
//
pointF.y
=
mHeight
-dHeight;
//
}
return
pointF;
}
public
void
addHeart()
{
final
ImageView
imageView
=
new
ImageView(getContext());
//
随机选一个爱心
imageView.setImageDrawable(drawables[random.nextInt(6)]);
imageView.setLayoutParams(lp);
addView(imageView);
AnimatorSet
finalSet
=
new
AnimatorSet();
AnimatorSet
enterAnimatorSet
=
getEnterAnimator(imageView);//入场动画
ValueAnimator
bezierValueAnimator
=
getBezierValueAnimator(imageView);//贝塞尔曲线路径动画
finalSet.playSequentially(enterAnimatorSet,
bezierValueAnimator);
//
finalSet.playSequentially(bezierValueAnimator);
finalSet.setInterpolator(mInterpolators[random.nextInt(4)]);
finalSet.setTarget(imageView);
finalSet.addListener(new
AnimatorListenerAdapter()
{
@Override
public
void
onAnimationEnd(Animator
animation)
{
super.onAnimationEnd(animation);
removeView((imageView));//删除爱心
}
});
finalSet.star
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年材料能源行业技能考试-风电运检笔试参考题库含答案
- 2024年机械制造行业技能考试-电(气)焊工安全知识应知应会笔试参考题库含答案
- 水污染防治设备项目商业计划书及实施方案|瑞克咨询|2024年编|
- 五年高考高考英语真题分项详解 专题20 情景交际和特殊句式(含解析)-人教高三全册英语试题
- HRN-40松香系中性施胶剂项目市场研究报告及运营管理方案|瑞克咨询|2024年编|
- 2024年文化教育职业技能考试-教育信息化应用网络笔试参考题库含答案
- 2024年操作工技能考核考试-电子设备装接工笔试参考题库含答案
- 2024年建筑考试-房地产经纪专业人员笔试参考题库含答案
- 2024年广东住院医师-广东住院医师神经内科学笔试参考题库含答案
- 2024年岗位知识竞赛-中国石油加氢车间设备知识笔试参考题库含答案
- 2022小学科学课程标准解读ppt
- GB/T 5075-2016电力金具名词术语
- 高中英语阅读课堂活动设计讲座课件
- 13-旋风分离器说明书
- 瘙痒诊断与治疗指南课件
- 部编版七年级语文下册课后习题参考答案汇总
- 机打发票销货清单
- 《梦游天姥吟留别》《登高》对比阅读教学设计 统编版高中语文必修上册第三单元
- 最新临床输血指南课件
- 《 民航服务心理学》考试题及参考答案
- 人教版八年级上英语各单元主题思维导图课件
评论
0/150
提交评论