版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】怎么在Android中利用三階貝塞爾曲線繪制運(yùn)動(dòng)軌跡
怎么在Android中利用三階貝塞爾曲線繪制運(yùn)動(dòng)軌跡?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面在下將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。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位置是相對(duì)于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);
//
初始化插補(bǔ)器
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();
//手動(dòng)設(shè)置寬高
dWidth
=
dip2px(getContext(),
40);
dHeight
=
dip2px(getContext(),
40);
lp
=
new
LayoutParams(dWidth,
dHeight);
//設(shè)置view控件的起始位置
//
lp.addRule(CENTER_HORIZONTAL,
TRUE);//
這里的TRUE
要注意
不是true
lp.addRule(ALIGN_PARENT_RIGHT,
TRUE);
lp.addRule(ALIGN_PARENT_BOTTOM,
TRUE);
}
/**
*
dp轉(zhuǎn)px值
*/
private
int
dip2px(Context
context,
float
dpValue)
{
float
scale
=
context.getResources().getDisplayMetrics().density;
return
(int)
(dpValue
*
scale
+
0.5f);
}
/**
*
進(jìn)場(chǎng)動(dòng)畫,三種同時(shí)播放
*
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)
{
//
初始化貝塞爾估值器
//隨機(jī)產(chǎn)生兩個(gè)點(diǎn),以確定一條3階貝塞爾曲線
BezierEvaluator
evaluator
=
new
BezierEvaluator(getPointF(2),
getPointF(1));
//
起點(diǎn)在底部中心位置,終點(diǎn)在底部隨機(jī)一個(gè)位置,改變new
PointF()中值來(lái)改變起始位置
//
ValueAnimator
animator
=
ValueAnimator.ofObject(evaluator,
new
PointF((mWidth
-
dWidth)
/
//
2,
mHeight
-
dHeight),
new
PointF(random.nextInt(getWidth()),
0));
//
起點(diǎn)在右下角位置,終點(diǎn)在左上角位置
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)
{
//
這里獲取到貝塞爾曲線計(jì)算出來(lái)的的x
y值
賦值給view
這樣就能讓愛心隨著曲線走啦
PointF
pointF
=
(PointF)
valueAnimator.getAnimatedValue();
target.setX(pointF.x);
target.setY(pointF.y);
//
alpha動(dòng)畫,根據(jù)運(yùn)動(dòng)距離改變透明度
//
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都是隨機(jī),因此可以產(chǎn)生n多種軌跡
pointF.x
=
random.nextInt(mWidth);//0~loveLayout.Width
//為了美觀,建議盡量保證P2在P1上面,那怎么做呢??
//只需要將該布局的高度分為上下兩部分,讓p1只能在下面部分范圍內(nèi)變化(1/2height~height),讓p2只能在上面部分范圍內(nèi)變化(0~1/2height),因?yàn)樽鴺?biāo)系是倒著的;
//0~loveLayout.Height/2
if
(i
==
1)
{
pointF.y
=
random.nextInt(mHeight
/
2)
+
mHeight
/
2;//P1點(diǎn)Y軸坐標(biāo)變化
}
else
if
(i
==
2)
{//P2點(diǎn)Y軸坐標(biāo)變化
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());
//
隨機(jī)選一個(gè)愛心
imageView.setImageDrawable(drawables[random.nextInt(6)]);
imageView.setLayoutParams(lp);
addView(imageView);
AnimatorSet
finalSet
=
new
AnimatorSet();
AnimatorSet
enterAnimatorSet
=
getEnterAnimator(imageView);//入場(chǎng)動(dòng)畫
ValueAnimator
bezierValueAnimator
=
getBezierValueAnimator(imageView);//貝塞爾曲線路徑動(dòng)畫
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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年受歡迎人事代理合同
- 2025年生態(tài)環(huán)保技術(shù)推廣合同
- 二零二五年度木材行業(yè)信息化建設(shè)與數(shù)據(jù)服務(wù)合同2篇
- 鍍錫平板軋材項(xiàng)目可行性研究報(bào)告建議書申請(qǐng)備案
- 2020-2025年中國(guó)半導(dǎo)體激光治療機(jī)行業(yè)市場(chǎng)運(yùn)營(yíng)現(xiàn)狀及投資戰(zhàn)略咨詢報(bào)告
- 貴陽(yáng)2025年租賃合同含租賃雙方權(quán)利義務(wù)及爭(zhēng)議解決機(jī)制2篇
- 2025年度文化創(chuàng)意產(chǎn)業(yè)知識(shí)產(chǎn)權(quán)運(yùn)營(yíng)框架協(xié)議
- 二零二五年度道路工程施工合同糾紛處理協(xié)議
- 二零二五年度綠色食品連鎖店進(jìn)貨合同電子版
- 二零二五年度2025年度生物制藥行業(yè)研究員聘用協(xié)議
- 人教版物理八年級(jí)下冊(cè) 專項(xiàng)訓(xùn)練卷 (一)力、運(yùn)動(dòng)和力(含答案)
- 山東省房屋市政工程安全監(jiān)督機(jī)構(gòu)人員業(yè)務(wù)能力考試題庫(kù)-中(多選題)
- 重慶市2023-2024學(xué)年七年級(jí)上學(xué)期期末考試數(shù)學(xué)試題(含答案)
- 2024年中考語(yǔ)文滿分作文6篇(含題目)
- 北師大版 2024-2025學(xué)年四年級(jí)數(shù)學(xué)上冊(cè)典型例題系列第三單元:行程問題“拓展型”專項(xiàng)練習(xí)(原卷版+解析)
- 2023年譯林版英語(yǔ)五年級(jí)下冊(cè)Units-1-2單元測(cè)試卷-含答案
- 施工管理中的文檔管理方法與要求
- DL∕T 547-2020 電力系統(tǒng)光纖通信運(yùn)行管理規(guī)程
- 種子輪投資協(xié)議
- 執(zhí)行依據(jù)主文范文(通用4篇)
- 浙教版七年級(jí)數(shù)學(xué)下冊(cè)全冊(cè)課件
評(píng)論
0/150
提交評(píng)論