無聊寫了一下 翻頭牌的效果。享受了一把 皇帝翻妃子的快感。因爲這個 小demo很簡單,就是用來熟悉一下objectAnimator的大概用法,所以我們深入淺出,直接上代碼。
代碼結構很簡單;
anim_in 這個動畫類xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--消失-->
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0"/>
<!--旋轉-->
<objectAnimator
android:duration="@integer/anim_length"
android:propertyName="rotationY"
android:valueFrom="-180"
android:valueTo="0"/>
<objectAnimator
android:duration="3000"
android:propertyName="rotationY"
android:valueFrom="-180"
android:valueTo="0">
</objectAnimator>
<!--出現-->
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:startOffset="@integer/anim_half_length"
android:valueFrom="0.0"
android:valueTo="1.0"/>
</set>
在<set>標籤中 進行 <objectAnimator>標籤的動畫組合,duration="3000" 動畫持續時間
<pre name="code" class="java">propertyName: 動畫的方式 選擇是旋轉 哪個軸,還是 縮放,平移這些效果
<pre name="code" class="java">valueFrom value to 從哪裏開始到 哪裏結束這類的 這些屬性還是比較簡單 ,想詳細指導 關於這些的可以自己百度資料看一下
下面我們看一下簡單的邏輯實現:
MainActivity
package me.chunyu.spike.flip_anim_demo;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.FrameLayout;
import butterknife.Bind;
import butterknife.ButterKnife;
import me.chunyu.spike.wcl_flip_anim_demo.R;
public class MainActivity extends AppCompatActivity {
@Bind(R.id.main_fl_container) FrameLayout mFlContainer;
//反面
@Bind(R.id.main_fl_card_back) FrameLayout mFlCardBack;
//正面
@Bind(R.id.main_fl_card_front) FrameLayout mFlCardFront;
private AnimatorSet mRightOutSet; // 右出動畫
private AnimatorSet mLeftInSet; // 左入動畫
private boolean mIsShowBack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setAnimators(); // 設置動畫
setCameraDistance(); // 設置鏡頭距離
}
// 設置動畫
private void setAnimators() {
mRightOutSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.anim_out);
mLeftInSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.anim_in);
//卡牌翻轉位置從右往左開始到結束
// 設置點擊事件
mRightOutSet.addListener(new AnimatorListenerAdapter() {
@Override public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
//在動畫開始執行的這個過程中,設置不能點擊,不然會bao空指針等 不可預見的錯誤
mFlContainer.setClickable(false);
}
});
mLeftInSet.addListener(new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mFlContainer.setClickable(true);
}
});
}
// 改變視角距離, 貼近屏幕<pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'宋體';font-size:13.5pt;"><span style="color:#808080;">就是相當於我們打遊戲的的時候滾輪放大縮小視角的感覺</span>
private void setCameraDistance() { int distance = 16000; float scale = getResources().getDisplayMetrics().density * distance; mFlCardFront.setCameraDistance(scale); mFlCardBack.setCameraDistance(scale); } // 翻轉卡片 public void flipCard(View view)
{ // 正面朝上 if (!mIsShowBack) { mRightOutSet.setTarget(mFlCardFront); mLeftInSet.setTarget(mFlCardBack); mRightOutSet.start(); mLeftInSet.start(); mIsShowBack = true; } else { // 背面朝上 mRightOutSet.setTarget(mFlCardBack); mLeftInSet.setTarget(mFlCardFront); mRightOutSet.start();
mLeftInSet.start(); mIsShowBack = false; } } @Override protected void onDestroy() { super.onDestroy(); ButterKnife.unbind(this); }}
在這裏面 我們 看一下 這個 float scale = getResources().getDisplayMetrics().density * distance;
在這裏 float scale = getResources().getDisplayMetrics().density;//這個得到的不應該叫做密度,應該是密度的一個比例。不是真實的屏幕密度,而是相對於某個值的屏幕密度。
//也可以說是相對密度
/**
* The logical density of the display. This is a scaling factor for the
* Density Independent Pixel unit, where one DIP is one pixel on an
* approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
* providing the baseline of the system's display. Thus on a 160dpi
* screen this density value will be 1; on a 120 dpi screen it would be
* .75; etc.
*
* This value does not exactly follow the real screen size (as given by
* xdpi and ydpi, but rather is used to scale the size of the overall UI
* in steps based on gross changes in the display dpi. For example, a
* 240x320 screen will have a density of 1 even if its width is
* 1.8", 1.3", etc. However, if the screen resolution is increased to
* 320x480 but the screen size remained 1.5"x2" then the density would
* be increased (probably to 1.5).
*/
/**
* 顯示器的邏輯密度,這是【獨立的像素密度單位(首先明白dip是個單位)】的一個縮放因子,
* 在屏幕密度大約爲160dpi的屏幕上,一個dip等於一個px,這個提供了系統顯示器的一個基線(這句我實在翻譯不了)。
* 例如:屏幕爲240*320的手機屏幕,其尺寸爲 1.5"*2" 也就是1.5英寸乘2英寸的屏幕
* 它的dpi(屏幕像素密度,也就是每英寸的像素數,dpi是dot per inch的縮寫)大約就爲160dpi,
* 所以在這個手機上dp和px的長度(可以說是長度,最起碼從你的視覺感官上來說是這樣的)是相等的。
* 因此在一個屏幕密度爲160dpi的手機屏幕上density的值爲1,而在120dpi的手機上爲0.75等等
* (這裏有一句話沒翻譯,實在讀不通順,不過通過下面的舉例應該能看懂)
* 例如:一個240*320的屏幕儘管他的屏幕尺寸爲1.8"*1.3",(我算了下這個的dpi大約爲180dpi多點)
* 但是它的density還是1(也就是說取了近似值)
* 然而,如果屏幕分辨率增加到320*480 但是屏幕尺寸仍然保持1.5"*2" 的時候(和最開始的例子比較)
* 這個手機的density將會增加(可能會增加到1.5)
*/
在做ui的時候,可能ui給的是px這個單位,這個時候大家可以去轉換一下,或者用 “標你妹”來進行丈量,
個人感覺這個 還是蠻好用的。
demo 下載地址:http://download.csdn.net/detail/ningzhouxu/9622899
歡迎討論羣:166120952 共同進步,學習