Android之實現京東底部新增到購物車的效果
##前言
美好的雙休日快要結束了,昨天玩了一天,今天在家看了一整天的書,大體看了網路框架搭建的一個流程,自己也試了下,有些小問題,還在研究中。用過京東APP的都知道在商品詳情頁底部有個新增到購物車的按鈕,一點選就會將商品以拋物線的形式放入購物車中,今天給大家帶來的就是類似購物車的效果。
##原理講解
將上面效果拆分成兩部分的話,就是拋物線+圖片縮放,拋物線關鍵點就是獲取Y座標,這裡直接套用網上的公式:
/** * 這裡是根據三個座標點計算出來的拋物線方程 * * @param x * @return */ private float getY(float x) { return a * x * x + 4 * x; }
整體的拋物線和縮放動畫使用PropertyValuesHolder,達到同步播放的效果。
通過PropertyValuesHolder.ofKeyframe(“translationY”, keyframes);實現商品的向左平移的效果,這裡面的keyframes是一個Keyframe物件的陣列,看如下的整體取值:
Keyframe[] keyframes = new Keyframe[(int) count]; final float keyStep = 1f / (float) count; float f = (float) (start_location[0] - end_location[0]) / count; float key = keyStep; for (int i = 0; i < count; ++i) { keyframes[i] = Keyframe.ofFloat(key, -i * f); key += keyStep; }
count是動畫在執行過程中的步數,這裡面拆分成300份,view在螢幕上向左平移時值為負數,因此Keyframe.ofFloat(key, -i * f),這裡面的f公式:
float f = (float) (start_location[0] - end_location[0]) / count;
sart_location[0]是獲取的新增購物車按鈕的X座標,end_location[0]是購物車小圖示的X座標,相減得到按鈕到購物車的距離,將距離進行平分,分成count份,因此通過for迴圈-i * f,進行向左的移動。
Y軸的平移,會發現先是向上平移(負數),平移到一半後,向下平移(正數),這樣構成一個平滑的拋物線,通過上面的Y座標的公式得出:
key = keyStep;
for (int i = 0; i < count; ++i) {
keyframes[i] = Keyframe.ofFloat(key, -getY(i + 1));
key += keyStep;
}
PropertyValuesHolder pvhY = PropertyValuesHolder.ofKeyframe("translationY", keyframes);
這時得到View進行拋物線移動時的X和Y座標,接著會看到View的縮放,縮放程式碼如下:
PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX",
1f, 0.5f);
PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY",
1f, 0.5f);
最後通過:
mObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(mShopView,
pvhX, pvhY, scaleX, scaleY).setDuration(1500);
獲取ObjectAnimator物件,進行start()就可動畫的播放。
##如何應用到專案中
這裡我建立了一個AnimUtils類,使用如下:
package com.example.addshowanimproject;
import com.example.addshowanimproject.animutil.AnimUtils;
import com.example.addshowanimproject.inter.IAddShopListener;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
public class MainActivity extends Activity {
/**
* 購物車小圖示
*/
private ImageView iv_shop;
/**
* 新增到購物車按鈕
*/
private LinearLayout ll_btn_add;
private AnimUtils mAnimUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initEvent();
}
/**
* View的初始化
*/
private void initViews(){
iv_shop=(ImageView) findViewById(R.id.iv_shop);
ll_btn_add=(LinearLayout) findViewById(R.id.ll_btn_add);
}
/**
* 註冊事件
*/
private void initEvent(){
final ImageView imageView=new ImageView(this);
imageView.setLayoutParams(new LayoutParams(30, 60));
imageView.setImageResource(R.drawable.biancheng);
ll_btn_add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.i("TAG","onClick");
if(mAnimUtils==null){
mAnimUtils=new AnimUtils(MainActivity.this, ll_btn_add, iv_shop, imageView);
}
mAnimUtils.addShopCart(new IAddShopListener() {
@Override
public void addSucess() {
Toast.makeText(MainActivity.this, "添加了一個商品", Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
程式碼很簡單,AnimUtils的初始化,接著呼叫AnimUtils的addShopCart方法進行動畫播放完畢的監聽。
以下是xml的佈局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_bright" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="@android:color/white"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_shop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/shopping_cart" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="購物車"
android:textColor="@android:color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_btn_add"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:background="@android:color/holo_red_light"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加入購物車"
android:textColor="@android:color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
當然有些人會說,你這購物車圖片在按鈕旁邊,那我如果在底部最左邊呢?放心,一樣可以支援,我們將xml改為如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_bright" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="@android:color/white"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_shop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/shopping_cart" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="購物車"
android:textColor="@android:color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="@+id/ll_btn_add"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:background="@android:color/holo_red_light"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加入購物車"
android:textColor="@android:color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
執行程式如下:
怎麼樣,是不是很方便。
以下是完整的github專案地址,歡迎star,fork。
github專案原始碼地址:點選【專案原始碼】