版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android怎么實現(xiàn)購物車添加商品動畫
這篇文章將為大家詳細(xì)講解有關(guān)Android怎么實現(xiàn)購物車添加商品動畫,在下覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。實現(xiàn)需求:在商品列表頁面,從列表Item添加商品的時候,需要一個動畫,仿佛是是往購物車?yán)锾砑由唐贰崿F(xiàn)思路:獲取起始點與終點的坐標(biāo),利用PathMeasure繪制貝塞爾曲線;為點擊的Item商品View設(shè)置屬性動畫;監(jiān)聽屬性動畫的update,改變View的坐標(biāo);實現(xiàn)效果:實現(xiàn)中會用到PathMeasure類:我們主要使用它兩個方法:1、獲取長度:/**
//獲取弧線的總長度(周長)
*
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為一個0-getLength()之間的值,根據(jù)這個值PathMeasure會計算出當(dāng)前點的坐標(biāo)封裝到pos中。上面這句話我們可以這么來理解,不管實際Path多么的復(fù)雜,PathMeasure都相當(dāng)于做了一個事情,就是把Path“拉直”,然后給了我們一個接口(getLength)告訴我們path的總長度,然后我們想要知道具體某一點的坐標(biāo),只需要用相對的distance去取即可,這樣就省去了自己用函數(shù)模擬path,然后計算獲取點坐標(biāo)的過程。代碼如下: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);
//二、計算動畫開始/結(jié)束點的坐標(biāo)的準(zhǔn)備工作
//得到父布局的起始點坐標(biāo)(用于輔助計算動畫開始/結(jié)束時的點的坐標(biāo))
int[]
parentLoc
=
new
int[2];
mRootRl.getLocationInWindow(parentLoc);
//得到商品圖片的坐標(biāo)(用于計算動畫開始的坐標(biāo))
int
startLoc[]
=
new
int[2];
imageView.getLocationInWindow(startLoc);
//得到購物車圖片的坐標(biāo)(用于計算動畫結(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;
//商品掉落后的終點坐標(biāo):購物車起始點-父布局起始點+購物車圖片的1/5
float
toX
=
endLoc[0]
-
parentLoc[0]
+
mCarImageView.getWidth()
/
5;
float
toY
=
endLoc[1]
-
parentLoc[1];
//開始繪制貝塞爾曲線
Path
path
=
new
Path();
path.moveTo(startX,
startY);
//使用二次薩貝爾曲線:注意第一個起始坐標(biāo)越大,貝塞爾曲線的橫向距離就會越大,一般按照下面的式子取即可
path.quadTo((startX
+
toX)
/
2,
startY,
toX,
toY);
mPathMeasure
=
new
PathMeasure(path,
false);
//屬性動畫
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)
{
//
購物車的數(shù)量加1
mCount++;
mCountTv.setText(String.valueOf(mCount));
//
把移動的圖片imageview從父布局里移除
mRootRl.removeView(view);
//shopImg
開始一個放大動畫
Animation
scaleAnim
=
AnimationUtils.loadAnimation(GoodsListActivity.this,
R.anim.shop_
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度農(nóng)田種植技術(shù)指導(dǎo)承包合同4篇
- 2025年度充電樁智能監(jiān)控系統(tǒng)采購合同樣本3篇
- 2025年度個人藝術(shù)品收藏鑒定合同4篇
- 二零二五年度企事業(yè)單位食堂承包與營養(yǎng)搭配合同4篇
- 2025年個人技術(shù)入股股權(quán)確認(rèn)合同范本2篇
- 門市轉(zhuǎn)租合同
- 2025年度個人住宅地下室防水加固合同范本8篇
- 2025年度個人二手房買賣協(xié)議書范本:房產(chǎn)交易全程專業(yè)服務(wù)合同
- 2025年度個人債務(wù)重組合同范本大全4篇
- 2025年度茶青種植基地土地流轉(zhuǎn)合同范本4篇
- GB/T 43650-2024野生動物及其制品DNA物種鑒定技術(shù)規(guī)程
- 2024年南京鐵道職業(yè)技術(shù)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年參考題庫含答案解析
- 暴發(fā)性心肌炎查房
- 口腔醫(yī)學(xué)中的人工智能應(yīng)用培訓(xùn)課件
- 工程質(zhì)保金返還審批單
- 【可行性報告】2023年電動自行車項目可行性研究分析報告
- 五月天歌詞全集
- 商品退換貨申請表模板
- 實習(xí)單位鑒定表(模板)
- 數(shù)字媒體應(yīng)用技術(shù)專業(yè)調(diào)研方案
- 2023年常州市新課結(jié)束考試九年級數(shù)學(xué)試卷(含答案)
評論
0/150
提交評論