今天做到一個模塊,需要做一個控件,能夠正反面都有視圖,點擊就能翻轉(zhuǎn)切換的那種(對對對,就是你想的那種?。?。
好好思考了一下,應(yīng)該不怎么難,于是便開始動手自己寫一個簡易的。
大體思路
兩個疊加在一起的視圖,一個可見,一個不可見,分別設(shè)置動畫效果(繞Y軸旋轉(zhuǎn)),正面視圖從0-90度旋轉(zhuǎn),旋轉(zhuǎn)結(jié)束后,隱藏正面視圖,顯示背面視圖,然后背面視圖從-90-0度旋轉(zhuǎn) ,形成了一個完整的動畫流程。(具體可見下面效果圖)
1.首先需要兩個視圖。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sundae.FrontAndBackAnimator.MainActivity">
<RelativeLayout
android:id="@+id/card_back"
android:layout_width="match_parent"
android:layout_height="220dp"
android:layout_centerHorizontal="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="102dp"
android:background="@android:color/holo_blue_bright"
android:gravity="center"
android:visibility="gone">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="你好世界!"
android:textSize="30sp"
android:textStyle="bold" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/textView"
android:layout_alignStart="@+id/textView"
android:layout_below="@+id/textView"
android:layout_marginTop="12dp"
android:text="Button" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/card_face"
android:layout_width="match_parent"
android:layout_height="220dp"
android:layout_centerHorizontal="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="102dp"
android:background="@android:color/holo_orange_dark"
android:gravity="center"
android:visibility="visible">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hello World!"
android:textSize="30sp"
android:textStyle="bold" />
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/textView2"
android:layout_below="@+id/textView2"
android:layout_marginTop="12dp"
android:ems="10"
android:hint="請輸入。。。"
android:inputType="textPersonName" />
</RelativeLayout>
</RelativeLayout>
得到如下效果

這其實是兩個視圖疊加在一起的,位置和寬高相同,一個在下層,一個在上層。
2.接下來需要實現(xiàn)翻轉(zhuǎn)的動畫效果
使用ObjectAnimator,需要設(shè)置這幾個屬性
toBackObjectAnimator = new ObjectAnimator();
toBackObjectAnimator.setFloatValues(0f , 90f);
///動畫更新值的范圍(設(shè)置為0-90度)
toBackObjectAnimator.setDuration(duration); ///動畫的時長
toBackObjectAnimator.setPropertyName("rotationY");
///所更改的object屬性 這里是y軸角度
toBackObjectAnimator.setTarget(faceView);
///設(shè)置需要應(yīng)用的視圖
toBackObjectAnimator.addUpdateListener()可以添加動畫更新的監(jiān)聽器
然后就可以使用toBackObjectAnimator.start()開始動畫了
3.動畫流程
(1)正面視圖設(shè)置動畫從0-90度旋轉(zhuǎn)。
(2)旋轉(zhuǎn)結(jié)束后,隱藏正面視圖,顯示背面視圖。
(3)背面視圖開始旋轉(zhuǎn),從-90-0度旋轉(zhuǎn)。
(4)結(jié)束
這是一個流程。
4.動畫顯示距離的問題
這時你運行一下后會發(fā)現(xiàn)這樣的問題

(?ì _ í?)我去,動畫怎么就糊臉上了呢。
這是繞Y軸旋轉(zhuǎn)的時候會出現(xiàn)的現(xiàn)象,需要調(diào)整視距。(初始化的時候調(diào)用一次即可,設(shè)置需要設(shè)置的view)
/**
* rotationY屬性變換時需要調(diào)整相機距離,否則會影響用戶體驗
*/
private void setCameraDistance() {
int distance = 16000;
float scale = context.getResources().getDisplayMetrics().density * distance;
view.setCameraDistance(scale); //設(shè)置相機視距距離
view1.setCameraDistance(scale); //需要設(shè)置的都設(shè)置一下
}
5.一個線性動畫的問題
當你這樣寫好后還會發(fā)現(xiàn)一個問題,動畫update的值并不是一個線性的
而是以一種類似S型曲線的值來變幻,

這樣的減速-加速-減速的曲線。
而我需要的是線性的動畫效果(速度一致)
這時就需要用到一個叫插值器(TimeInterpolator)的神奇的東西。
/**
* 線性值插值器
*/
class LinearAnim implements TimeInterpolator{
@Override
public float getInterpolation(float input) {
//Log.e("TAG", "getInterpolation: input : " + input );
return input;
}
}
寫一個類使用TimeInterpolator接口
實現(xiàn)getInterpolation方法。
可以Log看一下input的值,實現(xiàn)線性效果的話直接return input就可以了。
寫好想要的效果后對ObjectAnimator設(shè)置一下就行了
toBackObjectAnimator.setInterpolator(new LinearAnim());
后續(xù)會對TimeInterpolator進行一些詳細的學(xué)習,挺好玩的一個東西,能夠?qū)崿F(xiàn)很多效果。
6.上面的工作完成后能夠?qū)崿F(xiàn)如下效果(GIF沒有實際流暢)

OK,基本的功能就搞定了,剩下的就是一些邏輯性的問題了
我已經(jīng)做好了一個工具類可以參考或直接調(diào)用
FrontAndBackView.java
調(diào)用方法如下:
faceAndBackView = new FrontAndBackView(getApplicationContext() , frontView, backView);
//faceAndBackView.setDuration(2000); 設(shè)置時常
添加點擊監(jiān)聽器調(diào)用toggle方法。
@Override
public void onClick(View v) {
if(v.getId() == R.id.front_view || v.getId() == R.id.back_view)
faceAndBackView.toggle();
}
這樣就可以直接使用了,可以循環(huán)哦。
ps:只是一個初步版本,后續(xù)有機會還會繼續(xù)完善,如果發(fā)現(xiàn)有bug或者有什么建議請聯(lián)系我哦??,一起學(xué)習。
948820549@qq.com