Android頁面翻轉動畫(模仿CSDN賬號登入的翻轉效果)
阿新 • • 發佈:2019-01-27
昨天下載了CSDN的APP,進入多種方式選擇登入的頁面,然後我選擇用CSDN賬號登入,發現有頁面翻轉的效果進入登入頁面。瞬時感覺好炫,自己感覺效果很好。平時別的APP登入的時候,就是直接進入登入頁面,沒有任何效果。這次看到旋轉的效果,頓時眼前一亮,所以我就研究了一下,想做個類似的效果。這邊我主要用了兩個Fragment和自定義的動畫效果。下面上幾張圖,按照CSDN登入UI做的,UI做的比較粗糙,可還能將就看。
多種方式選擇登入介面
點選CSDN賬號登入後的旋轉介面,(因為不會用動畫展示,只能截圖看看了)
登入介面
接下來,我們開始這個Android程式的建立。
第一步,新建民名為RotationLoginDemo的Android專案,從圖我們可以看到翻轉前後有兩個介面,那麼這兩個介面從用什麼做的呢?我不知道他們是怎麼實現的,這裡我用了兩個Fragment,分別為SelectLoginFragment和LoginFragment。接著就開始建這兩個Fragment所對應的佈局檔案fragment_select_login和fragment_login,下面的就是這兩個佈局檔案的程式碼。
fragment_select_login.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/layout_bottom" > <LinearLayout android:id="@+id/text_sdn" android:layout_width="match_parent" android:layout_height="80dip" android:layout_centerInParent="true" android:gravity="center" android:orientation="horizontal" > <TextView android:id="@+id/text_c" android:layout_width="wrap_content" android:layout_height="80dip" android:gravity="center" android:text="C " android:textColor="#CC0000" android:textSize="60sp" /> <TextView android:layout_width="wrap_content" android:layout_height="80dip" android:gravity="center" android:text="S D N" android:textColor="#000000" android:textSize="60sp" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="30dip" android:layout_below="@id/text_sdn" android:gravity="center" android:text="全 球 最 大 的 中 文 IT 社 區" android:textColor="#000000" android:textSize="20sp" /> </RelativeLayout> <LinearLayout android:id="@+id/layout_bottom" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="vertical" android:paddingLeft="10dip" android:paddingRight="10dip" > <Button android:id="@+id/btn_csdn_login" style="?android:attr/buttonBarButtonStyle" android:layout_width="match_parent" android:layout_height="50dip" android:background="@drawable/bg_btn" android:text="CSDN賬號登入" android:textColor="#666666" android:textSize="16sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip" android:orientation="horizontal" > <Button style="?android:attr/buttonBarButtonStyle" android:layout_width="0dip" android:layout_height="40dip" android:layout_marginRight="10dip" android:layout_weight="1" android:background="@drawable/bg_btn" android:text="微博" android:textColor="#666666" android:textSize="16sp" /> <Button style="?android:attr/buttonBarButtonStyle" android:layout_width="0dip" android:layout_height="40dip" android:layout_marginRight="10dip" android:layout_weight="1" android:background="@drawable/bg_btn" android:text="微信" android:textColor="#666666" android:textSize="16sp" /> <Button style="?android:attr/buttonBarButtonStyle" android:layout_width="0dip" android:layout_height="40dip" android:layout_weight="1" android:background="@drawable/bg_btn" android:text="QQ" android:textColor="#666666" android:textSize="16sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dip" android:layout_marginTop="30dip" android:gravity="center" android:text="建立賬號" android:textColor="#666666" android:textSize="16sp" /> </LinearLayout> </LinearLayout> </RelativeLayout>
fragment_login.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical"
android:padding="16dp" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/text_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
android:textColor="#000000"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center_horizontal"
android:lineSpacingMultiplier="1.2"
android:text="登入"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
<EditText
style="@android:style/Widget.TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:background="@null"
android:hint="輸入使用者名稱"
android:textSize="16sp" />
<EditText
style="@android:style/Widget.TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dip"
android:layout_marginTop="10dip"
android:background="@null"
android:hint="輸入密碼"
android:textSize="16sp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_btn"
android:text="登 錄" />
</LinearLayout>
第二步,自定義動畫:
在res資料夾下新建檔名為animator,下面具體結構如下圖:
下面為四個動畫的xml的程式碼:
left_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Before rotating, immediately set the alpha to 0. -->
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:duration="0" />
<!-- Rotate. -->
<objectAnimator
android:valueFrom="-180"
android:valueTo="0"
android:propertyName="rotationY"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:duration="1000" />
<!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
<objectAnimator
android:valueFrom="0.0"
android:valueTo="1.0"
android:propertyName="alpha"
android:startOffset="500"
android:duration="1" />
</set>
left_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Rotate. -->
<objectAnimator
android:valueFrom="0"
android:valueTo="180"
android:propertyName="rotationY"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:duration="1000" />
<!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:startOffset="500"
android:duration="1" />
</set>
right_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Before rotating, immediately set the alpha to 0. -->
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:duration="0" />
<!-- Rotate. -->
<objectAnimator
android:valueFrom="180"
android:valueTo="0"
android:propertyName="rotationY"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:duration="1000" />
<!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
<objectAnimator
android:valueFrom="0.0"
android:valueTo="1.0"
android:propertyName="alpha"
android:startOffset="500"
android:duration="1" />
</set>
right_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Rotate. -->
<objectAnimator
android:valueFrom="0"
android:valueTo="-180"
android:propertyName="rotationY"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:duration="1000" />
<!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:startOffset="500"
android:duration="1" />
</set>
第三步,建立Activity
package com.example.rotationcarddemo;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
@SuppressLint("NewApi")
public class MainActivity extends Activity implements FragmentManager.OnBackStackChangedListener
{
private boolean mShowingBack = false;
private int left_in = R.animator.left_in;
private int left_out = R.animator.left_out;
private int right_in = R.animator.right_in;
private int right_out = R.animator.right_out;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//判斷<span style="font-family: Arial, Helvetica, sans-serif;">savedInstanceState 是否為null,如果為null,則說明這是建立的全新的物件,如果不為null,則是重建上一次銷燬的物件</span>
if (savedInstanceState == null)
{
getFragmentManager().beginTransaction().add(R.id.container, new SelectLoginFragment())
.commit();
}
else
{
mShowingBack = getFragmentManager().getBackStackEntryCount() > 0;
}
getFragmentManager().addOnBackStackChangedListener(this);
}
/**
* 選擇登入方式介面
*/
public class SelectLoginFragment extends Fragment
{
public SelectLoginFragment()
{
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
View rootView = (View) inflater.inflate(R.layout.fragment_select_login, container,
false);
rootView.findViewById(R.id.btn_csdn_login).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
AnimationRotate(new LoginFragment(), left_in, left_out, right_in, right_out);
}
});
return rootView;
}
}
/**
* 登入頁面
*/
public class LoginFragment extends Fragment
{
public LoginFragment()
{
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
View rootView = (View) inflater.inflate(R.layout.fragment_login, container, false);
rootView.findViewById(R.id.text_cancel).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
AnimationRotate(new SelectLoginFragment(), right_in, right_out, left_in,
left_out);
}
});
return rootView;
}
}
/**
* 旋轉動畫
*/
private void AnimationRotate(Fragment fragment, int x, int y, int z, int f)
{
if (mShowingBack)
{
getFragmentManager().popBackStack();
return;
}
mShowingBack = true;
getFragmentManager().beginTransaction().setCustomAnimations(x, y, z, f)
.replace(R.id.container, fragment).addToBackStack(null).commit();
}
@Override
public void onBackStackChanged()
{
mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);
}
}