版權(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)用開(kāi)發(fā)技術(shù)】Android怎么實(shí)現(xiàn)購(gòu)物車添加商品動(dòng)畫
這篇文章將為大家詳細(xì)講解有關(guān)Android怎么實(shí)現(xiàn)購(gòu)物車添加商品動(dòng)畫,在下覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。實(shí)現(xiàn)需求:在商品列表頁(yè)面,從列表Item添加商品的時(shí)候,需要一個(gè)動(dòng)畫,仿佛是是往購(gòu)物車?yán)锾砑由唐贰?shí)現(xiàn)思路:獲取起始點(diǎn)與終點(diǎn)的坐標(biāo),利用PathMeasure繪制貝塞爾曲線;為點(diǎn)擊的Item商品View設(shè)置屬性動(dòng)畫;監(jiān)聽(tīng)屬性動(dòng)畫的update,改變View的坐標(biāo);實(shí)現(xiàn)效果:實(shí)現(xiàn)中會(huì)用到PathMeasure類:我們主要使用它兩個(gè)方法:1、獲取長(zhǎng)度:/**
//獲取弧線的總長(zhǎng)度(周長(zhǎng))
*
Return
the
total
length
of
the
current
contour,
or
0
if
no
path
is
*
associated
with
this
measure
object.
*/
public
float
getLength()
{
return
native_getLength(native_instance);//系統(tǒng)調(diào)用native
方法;
}2、獲取坐標(biāo):/**
*
Pins
distance
to
0
<=
distance
<=
getLength(),
and
then
computes
the
*
corresponding
position
and
tangent.
Returns
false
if
there
is
no
path,
*
or
a
zero-length
path
was
specified,
in
which
case
position
and
tangent
*
are
unchanged.
*
*
@param
distance
The
distance
along
the
current
contour
to
sample
*
@param
pos
If
not
null,
eturns
the
sampled
position
(x==[0],
y==[1])
*
@param
tan
If
not
null,
returns
the
sampled
tangent
(x==[0],
y==[1])
*
@return
false
if
there
was
no
path
associated
with
this
measure
object
*/
public
boolean
getPosTan(float
distance,
float
pos[],
float
tan[])
{
if
(pos
!=
null
&&
pos.length
<
2
||
tan
!=
null
&&
tan.length
<
2)
{
throw
new
ArrayIndexOutOfBoundsException();
}
return
native_getPosTan(native_instance,
distance,
pos,
tan);
}方法getPosTan(floatdistance,floatpos[],floattan[])-path為null,返回falsedistance為一個(gè)0-getLength()之間的值,根據(jù)這個(gè)值PathMeasure會(huì)計(jì)算出當(dāng)前點(diǎn)的坐標(biāo)封裝到pos中。上面這句話我們可以這么來(lái)理解,不管實(shí)際Path多么的復(fù)雜,PathMeasure都相當(dāng)于做了一個(gè)事情,就是把Path“拉直”,然后給了我們一個(gè)接口(getLength)告訴我們path的總長(zhǎng)度,然后我們想要知道具體某一點(diǎn)的坐標(biāo),只需要用相對(duì)的distance去取即可,這樣就省去了自己用函數(shù)模擬path,然后計(jì)算獲取點(diǎn)坐標(biāo)的過(guò)程。代碼如下:public
class
GoodsListActivity
extends
AppCompatActivity
{
private
RelativeLayout
mRootRl;
private
RecyclerView
mGoodsRecyclerView;
private
ImageView
mCarImageView;
private
TextView
mCountTv;
private
List<Bitmap>
mBitmapList
=
new
ArrayList<>();
private
PathMeasure
mPathMeasure;
private
float[]
mCurrentPosition
=
new
float[2];
private
int
mCount
=
0;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_goods_list);
initView();
initData();
GoodsAdapter
goodsAdapter
=
new
GoodsAdapter(mBitmapList);
mGoodsRecyclerView.setLayoutManager(new
LinearLayoutManager(this));
mGoodsRecyclerView.setAdapter(goodsAdapter);
}
private
void
initView(){
mGoodsRecyclerView
=
(RecyclerView)findViewById(R.id.recyclerView);
mCarImageView
=
(ImageView)findViewById(R.id.imageview_shop_car);
mCountTv
=
(TextView)findViewById(R.id.tv_count);
mRootRl
=
(RelativeLayout)findViewById(R.id.rl_root);
}
private
void
initData(){
mBitmapList.add(BitmapFactory.decodeResource(getResources(),
R.drawable.car));
mBitmapList.add(BitmapFactory.decodeResource(getResources(),
R.drawable.car));
mBitmapList.add(BitmapFactory.decodeResource(getResources(),
R.drawable.car));
}
class
GoodsAdapter
extends
RecyclerView.Adapter<GoodsViewHolder>{
private
List<Bitmap>
mData;
public
GoodsAdapter(List<Bitmap>
data)
{
mData
=
data;
}
@Override
public
GoodsViewHolder
onCreateViewHolder(ViewGroup
parent,
int
viewType)
{
View
itemView
=
LayoutInflater.from(GoodsListActivity.this)
.inflate(R.layout.rv_goods_item,
parent,
false);
return
new
GoodsViewHolder(itemView);
}
@Override
public
void
onBindViewHolder(final
GoodsViewHolder
holder,
int
position)
{
holder.ivGood.setImageBitmap(mData.get(position));
holder.tvBuy.setOnClickListener(new
View.OnClickListener()
{
@Override
public
void
onClick(View
v)
{
addGoodToCar(holder.ivGood);
}
});
}
@Override
public
int
getItemCount()
{
return
mData
!=
null
?
mData.size()
:
0;
}
}
private
void
addGoodToCar(ImageView
imageView){
final
ImageView
view
=
new
ImageView(GoodsListActivity.this);
view.setImageDrawable(imageView.getDrawable());
RelativeLayout.LayoutParams
layoutParams
=
new
RelativeLayout.LayoutParams(100,
100);
mRootRl.addView(view,
layoutParams);
//二、計(jì)算動(dòng)畫開(kāi)始/結(jié)束點(diǎn)的坐標(biāo)的準(zhǔn)備工作
//得到父布局的起始點(diǎn)坐標(biāo)(用于輔助計(jì)算動(dòng)畫開(kāi)始/結(jié)束時(shí)的點(diǎn)的坐標(biāo))
int[]
parentLoc
=
new
int[2];
mRootRl.getLocationInWindow(parentLoc);
//得到商品圖片的坐標(biāo)(用于計(jì)算動(dòng)畫開(kāi)始的坐標(biāo))
int
startLoc[]
=
new
int[2];
imageView.getLocationInWindow(startLoc);
//得到購(gòu)物車圖片的坐標(biāo)(用于計(jì)算動(dòng)畫結(jié)束后的坐標(biāo))
int
endLoc[]
=
new
int[2];
mCarImageView.getLocationInWindow(endLoc);
float
startX
=
startLoc[0]
-
parentLoc[0]
+
imageView.getWidth()/2;
float
startY
=
startLoc[1]
-
parentLoc[1]
+
imageView.getHeight()/2;
//商品掉落后的終點(diǎn)坐標(biāo):購(gòu)物車起始點(diǎn)-父布局起始點(diǎn)+購(gòu)物車圖片的1/5
float
toX
=
endLoc[0]
-
parentLoc[0]
+
mCarImageView.getWidth()
/
5;
float
toY
=
endLoc[1]
-
parentLoc[1];
//開(kāi)始繪制貝塞爾曲線
Path
path
=
new
Path();
path.moveTo(startX,
startY);
//使用二次薩貝爾曲線:注意第一個(gè)起始坐標(biāo)越大,貝塞爾曲線的橫向距離就會(huì)越大,一般按照下面的式子取即可
path.quadTo((startX
+
toX)
/
2,
startY,
toX,
toY);
mPathMeasure
=
new
PathMeasure(path,
false);
//屬性動(dòng)畫
ValueAnimator
valueAnimator
=
ValueAnimator.ofFloat(0,
mPathMeasure.getLength());
valueAnimator.setDuration(1000);
valueAnimator.setInterpolator(new
LinearInterpolator());
valueAnimator.addUpdateListener(new
ValueAnimator.AnimatorUpdateListener()
{
@Override
public
void
onAnimationUpdate(ValueAnimator
animation)
{
float
value
=
(float)animation.getAnimatedValue();
mPathMeasure.getPosTan(value,
mCurrentPosition,
null);
view.setTranslationX(mCurrentPosition[0]);
view.setTranslationY(mCurrentPosition[1]);
}
});
valueAnimator.addListener(new
Animator.AnimatorListener()
{
@Override
public
void
onAnimationStart(Animator
animation)
{
}
@Override
public
void
onAnimationEnd(Animator
animation)
{
//
購(gòu)物車的數(shù)量加1
mCount++;
mCountTv.setText(String.valueOf(mCount));
//
把移動(dòng)的圖片imageview從父布局里移除
mRootRl.removeView(view);
//shopImg
開(kāi)始一個(gè)放大動(dòng)畫
Animation
scaleAnim
=
AnimationUtils.loadAnimation(GoodsListActivity.this,
R.anim.shop_
溫馨提示
- 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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 媒體行業(yè)內(nèi)容創(chuàng)作授權(quán)合同
- 城市智能交通管理系統(tǒng)建設(shè)合同
- 建材購(gòu)銷合同簡(jiǎn)單范本
- 協(xié)議酒店年度合同
- 標(biāo)準(zhǔn)體育場(chǎng)地租賃合同范文
- 技術(shù)開(kāi)發(fā)委托合同范本
- 進(jìn)出口合同的履行
- 員工借調(diào)服務(wù)合同
- 道路交通事故糾紛法律知識(shí)一本全-記錄
- 基于膜解剖的腹腔鏡與機(jī)器人結(jié)直腸腫瘤手術(shù)學(xué)-隨筆
- 外觀判定標(biāo)準(zhǔn)
- 江西上饒市2025屆數(shù)學(xué)高二上期末檢測(cè)試題含解析
- 腦卒中后吞咽障礙患者進(jìn)食護(hù)理團(tuán)體標(biāo)準(zhǔn)
- 工行人工智能風(fēng)控
- 2023風(fēng)電機(jī)組預(yù)應(yīng)力混凝土塔筒與基礎(chǔ)結(jié)構(gòu)設(shè)計(jì)標(biāo)準(zhǔn)
- 小學(xué)語(yǔ)文閱讀教學(xué)落實(shí)學(xué)生核心素養(yǎng)方法的研究-結(jié)題報(bào)告
- 一年級(jí)的成長(zhǎng)歷程
- 2024年南京鐵道職業(yè)技術(shù)學(xué)院高職單招(英語(yǔ)/數(shù)學(xué)/語(yǔ)文)筆試歷年參考題庫(kù)含答案解析
- 正月十五元宵節(jié)介紹課件
- 病毒性肺炎疾病演示課件
- 中考英語(yǔ)語(yǔ)法填空專項(xiàng)練習(xí)附答案(已排版-可直接打印)
評(píng)論
0/150
提交評(píng)論