贝塞尔曲线之购物车动画效果.docx

上传人:b****1 文档编号:2461515 上传时间:2023-05-03 格式:DOCX 页数:18 大小:91.87KB
下载 相关 举报
贝塞尔曲线之购物车动画效果.docx_第1页
第1页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第2页
第2页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第3页
第3页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第4页
第4页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第5页
第5页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第6页
第6页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第7页
第7页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第8页
第8页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第9页
第9页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第10页
第10页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第11页
第11页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第12页
第12页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第13页
第13页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第14页
第14页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第15页
第15页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第16页
第16页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第17页
第17页 / 共18页
贝塞尔曲线之购物车动画效果.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

贝塞尔曲线之购物车动画效果.docx

《贝塞尔曲线之购物车动画效果.docx》由会员分享,可在线阅读,更多相关《贝塞尔曲线之购物车动画效果.docx(18页珍藏版)》请在冰点文库上搜索。

贝塞尔曲线之购物车动画效果.docx

贝塞尔曲线之购物车动画效果

贝塞尔曲线之购物车动画效果

Question

贝塞尔曲线是什么?

贝塞尔曲线可以做什么?

怎么做?

Whatisit?

贝塞尔曲线在XX定义是贝塞尔曲线(Béziercurve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。

Usage

贝塞尔曲线根据不同点实现不同动态效果:

一阶贝塞尔曲线(两点),绘制成一条直线

看了上面贝塞尔曲线不同点不同效果后,相信大家都清楚贝塞尔曲线能干什么?

没错,贝塞尔曲线能造高逼格动画

就笔者目前了解的采用贝塞尔曲线实现的知名开源项目有:

QQ拖拽清除效果

纸飞机刷新动画

滴油刷新动画

波浪动画

到此大家是不是很兴奋,想更多了解如何造一个高逼格贝塞尔曲线动画。

接下来我就给大家讲述如何造一个基于贝塞尔曲线实现的购物车动画,大家擦亮眼睛啦~~

Howtodoit?

思路

确定动画起终点

在起终点之间使用二次贝塞尔曲线填充起终点之间点的轨迹

设置属性动画,ValueAnimator插值器,获取中间点的坐标

将执行动画控件的x、y坐标设为上面得到的中间点坐标

开启属性动画

当动画结束时的操作

知识点

Android中提供了绘制一阶、二阶、三阶的接口:

一阶接口:

publicvoidlineTo(floatx,floaty)

二阶接口:

publicvoidquadTo(floatx1,floaty1,floatx2,floaty2)

三阶接口:

publicvoidcubicTo(floatx1,floaty1,floatx2,floaty2,floatx3,floaty3)

PathMeasure使用

getLength()

理解booleangetPosTan(floatdistance,float[]pos,float[]tan)

如何获取控件在屏幕中的绝对坐标

int[]location=newint[2];view.getLocationInWindow(location);得到view在屏幕中的绝对坐标。

理解属性动画插值器ValueAnimator

Code

首先写购物车布局xml,代码如下:

[html]viewplaincopy在CODE上查看代码片派生到我的代码片

xmlversion="1.0"encoding="utf-8"?

>

android:

id="@+id/rly_bezier_curve_shopping_cart"

android:

layout_width="match_parent"

android:

layout_height="match_parent"

android:

paddingBottom="@dimen/activity_vertical_margin"

android:

paddingLeft="@dimen/activity_horizontal_margin"

android:

paddingRight="@dimen/activity_horizontal_margin"

android:

paddingTop="@dimen/activity_vertical_margin">

android:

id="@+id/fly_bezier_curve_shopping_cart"

android:

layout_width="match_parent"

android:

layout_height="wrap_content"

android:

layout_alignParentBottom="true"

android:

layout_alignParentLeft="true"

android:

paddingRight="30dp"

android:

layout_alignParentStart="true">

android:

id="@+id/iv_bezier_curve_shopping_cart"

android:

layout_width="40dp"

android:

layout_height="40dp"

android:

layout_gravity="right"

android:

src="@drawable/menu_shop_car_selected"/>

android:

id="@+id/tv_bezier_curve_shopping_cart_count"

android:

layout_width="wrap_content"

android:

layout_height="wrap_content"

android:

textColor="@color/white"

android:

background="@drawable/corner_view"

android:

text="0"

android:

layout_gravity="right"/>

android:

id="@+id/lv_bezier_curve_shopping_cart"

android:

layout_width="match_parent"

android:

layout_height="match_parent"

android:

layout_above="@+id/fly_bezier_curve_shopping_cart"/>

然后写购物车适配器、实体类,代码如下:

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

/**

*@className:

GoodsAdapter

*@classDescription:

购物车商品适配器

*@author:

leibing

*@createTime:

2016/09/28

*/

publicclassGoodsAdapterextendsBaseAdapter{

//数据源(购物车商品图片)

privateArrayListmData;

//布局

privateLayoutInflatermLayoutInflater;

//回调监听

privateCallBackListenermCallBackListener;

/**

*构造函数

*@authorleibing

*@createTime2016/09/28

*@lastModify2016/09/28

*@paramcontext上下文

*@parammData数据源(购物车商品图片)

*@return

*/

publicGoodsAdapter(Contextcontext,ArrayListmData){

mLayoutInflater=LayoutInflater.from(context);

this.mData=mData;

}

@Override

publicintgetCount(){

returnmData!

=null?

mData.size():

0;

}

@Override

publicObjectgetItem(inti){

returnmData!

=null?

mData.get(i):

null;

}

@Override

publiclonggetItemId(inti){

returni;

}

@Override

publicViewgetView(inti,Viewview,ViewGroupviewGroup){

ViewHolderviewHolder;

if(view==null){

view=mLayoutInflater.inflate(R.layout.adapter_shopping_cart_item,null);

viewHolder=ewViewHolder(view);

view.setTag(viewHolder);

}else{

//复用ViewHolder

viewHolder=(ViewHolder)view.getTag();

}

//更新UI

if(i

viewHolder.updateUI(mData.get(i));

returnview;

}

/**

*@className:

ViewHolder

*@classDescription:

商品ViewHolder

*@author:

leibing

*@createTime:

2016/09/28

*/

classViewHolder{

//显示商品图片

privateImageViewmShoppingCartItemIv;

/**

*构造函数

*@authorleibing

*@createTime2016/09/28

*@lastModify2016/09/28

*@paramview视图

*@return

*/

publicViewHolder(Viewview){

//findView

mShoppingCartItemIv=ImageView)view.findViewById(R.id.iv_shopping_cart_item);

//onClick

view.findViewById(R.id.tv_shopping_cart_item).setOnClickListener(

newView.OnClickListener(){

@Override

publicvoidonClick(Viewview){

if(mShoppingCartItemIv!

=null&&mCallBackListener!

=null)

mCallBackListener.callBackImg(mShoppingCartItemIv);

}

});

}

/**

*更新UI

*@authorleibing

*@createTime2016/09/28

*@lastModify2016/09/28

*@paramgoods商品实体对象

*@return

*/

publicvoidupdateUI(GoodsModelgoods){

if(goods!

=null

&&goods.getmGoodsBitmap()!

=null

&&mShoppingCartItemIv!

=null)

mShoppingCartItemIv.setImageBitmap(goods.getmGoodsBitmap());

}

}

/**

*设置回调监听

*@authorleibing

*@createTime2016/09/28

*@lastModify2016/09/28

*@parammCallBackListener回调监听

*@return

*/

publicvoidsetCallBackListener(CallBackListenermCallBackListener){

this.mCallBackListener=mCallBackListener;

}

/**

*@interfaceName:

CallBackListener

*@interfaceDescription:

回调监听

*@author:

leibing

*@createTime:

2016/09/28

*/

publicinterfaceCallBackListener{

voidcallBackImg(ImageViewgoodsImg);

}

}

然后写添加数据源以及设置适配器,代码如下:

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

//购物车父布局

privateRelativeLayoutmShoppingCartRly;

//购物车列表显示

privateListViewmShoppingCartLv;

//购物数目显示

privateTextViewmShoppingCartCountTv;

//购物车图片显示

privateImageViewmShoppingCartIv;

//购物车适配器

privateGoodsAdaptermGoodsAdapter;

//数据源(购物车商品图片)

privateArrayListmData;

//贝塞尔曲线中间过程点坐标

privatefloat[]mCurrentPosition=newfloat[2];

//路径测量

privatePathMeasuremPathMeasure;

//购物车商品数目

privateintgoodsCount=0;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//findView

mShoppingCartLv=(ListView)findViewById(R.id.lv_bezier_curve_shopping_cart);

mShoppingCartCountTv=(TextView)findViewById(R.id.tv_bezier_curve_shopping_cart_count);

mShoppingCartRly=(RelativeLayout)findViewById(R.id.rly_bezier_curve_shopping_cart);

mShoppingCartIv=(ImageView)findViewById(R.id.iv_bezier_curve_shopping_cart);

//是否显示购物车商品数目

isShowCartGoodsCount();

//添加数据源

addData();

//设置适配器

setAdapter();

}

/**

*设置适配器

*@authorleibing

*@createTime2016/09/28

*@lastModify2016/09/28

*@param

*@return

*/

privatevoidsetAdapter(){

//初始化适配器

mGoodsAdapter=newGoodsAdapter(this,mData);

//设置适配器监听

mGoodsAdapter.setCallBackListener(newGoodsAdapter.CallBackListener(){

@Override

publicvoidcallBackImg(ImageViewgoodsImg){

//添加商品到购物车

addGoodsToCart(goodsImg);

}

});

//设置适配器

mShoppingCartLv.setAdapter(mGoodsAdapter);

}

接下来写最重要的一块,添加商品到购物车,代码如下:

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

/**

*添加商品到购物车

*@authorleibing

*@createTime2016/09/28

*@lastModify2016/09/28

*@paramgoodsImg商品图标

*@return

*/

privatevoidaddGoodsToCart(ImageViewgoodsImg){

//创造出执行动画的主题goodsImg(这个图片就是执行动画的图片,从开始位置出发,经过一个抛物线(贝塞尔曲线),移动到购物车里)

finalImageViewgoods=newImageView(this);

goods.setImageDrawable(goodsImg.getDrawable());

RelativeLayout.LayoutParamsparams=newRelativeLayout.LayoutParams(100,100);

mShoppingCartRly.addView(goods,params);

//得到父布局的起始点坐标(用于辅助计算动画开始/结束时的点的坐标)

int[]parentLocation=ewint[2];

mShoppingCartRly.getLocationInWindow(parentLocation);

//得到商品图片的坐标(用于计算动画开始的坐标)

intstartLoc[]=newint[2];

goodsImg.getLocationInWindow(startLoc);

//得到购物车图片的坐标(用于计算动画结束后的坐标)

intendLoc[]=newint[2];

mShoppingCartIv.getLocationInWindow(endLoc);

//开始掉落的商品的起始点:

商品起始点-父布局起始点+该商品图片的一半

floatstartX=startLoc[0]-parentLocation[0]+goodsImg.getWidth()/2;

floatstartY=startLoc[1]-parentLocation[1]+goodsImg.getHeight()/2;

//商品掉落后的终点坐标:

购物车起始点-父布局起始点+购物车图片的1/5

floattoX=endLoc[0]-parentLocation[0]+mShoppingCartIv.getWidth()/5;

floattoY=endLoc[1]-parentLocation[1];

//开始绘制贝塞尔曲线

Pathpath=newPath();

//移动到起始点(贝塞尔曲线的起点)

path.moveTo(startX,startY);

//使用二阶贝塞尔曲线:

注意第一个起始坐标越大,贝塞尔曲线的横向距离就会越大,一般按照下面的式子取即可

path.quadTo((startX+toX)/2,startY,toX,toY);

//mPathMeasure用来计算贝塞尔曲线的曲线长度和贝塞尔曲线中间插值的坐标,如果是true,path会形成一个闭环

mPathMeasure=newPathMeasure(path,false);

//属性动画实现(从0到贝塞尔曲线的长度之间进行插值计算,获取中间过程的距离值)

ValueAnimatorvalueAnimator=ValueAnimator.ofFloat(0,mPathMeasure.getLength());

valueAnimator.setDuration(500);

//匀速线性插值器

valueAnimator.setInterpolator(newLinearInterpolator());

valueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){

@Override

publicvoidonAnimationUpdate(ValueAnimatoranimation){

//当插值计算进行时,获取中间的每个值,

//这里这个值是中间过程中的曲线长度(下面根据这个值来得出中间点的坐标值)

floatvalue=(Float)animation.getAnimatedValue();

//获取当前点坐标封装到mCurrentPosition

//booleangetPosTan(floatdistance,float[]pos,float[]tan):

//传入一个距离distance(0<=distance<=getLength()),然后会计算当前距离的坐标点和切线,pos会自动填充上坐标,这个方法很重要。

//mCurrentPosition此时就是中间距离点的坐标值

mPathMeasure.getPosTan(value,mCurrentPosition,null);

//移动的商品图片(动画图片)的坐标设置为该中间点的坐标

goods.setTranslationX(mCurrentPosition[0]);

goods.setTranslationY(mCurrentPosition[1]);

}

});

//开始执行动画

valueAnimator.start();

//动画结束后的处理

valueAnimator.addListener(newAnimator.AnimatorListener(){

@Oride

publicvoidonAnimationStart(Animatoranimation){

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2