国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

基于Android實現(xiàn)3D翻頁效果

2019-12-12 06:17:08
字體:
供稿:網(wǎng)友

最近做了一個簡單的3D效果翻頁特效,先說說我的思路吧,首先我這個翻頁效果并不是兩個Activity之間的跳轉(zhuǎn),而是在同一個activity類切換不同的view而已。我現(xiàn)在的做法是單擊一個button然后Gone當(dāng)前的布局,然后把需要呈現(xiàn)的布局visible,在隱藏當(dāng)前布局的時候啟動動畫,然后給動畫添加監(jiān)聽,在動畫結(jié)束時開始另外一個view的入場動畫就行了。
下面來看下我的主頁面的布局文件:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/container"  android:layout_width="fill_parent"  android:layout_height="fill_parent" >   <include  android:layout_width="fill_parent"  android:layout_height="fill_parent"  layout="@layout/layout2" />   <include  android:layout_width="fill_parent"  android:layout_height="fill_parent"  layout="@layout/layout1" />  </FrameLayout> 

我這個布局文件使用<include>標(biāo)簽包含了另外2個布局文件,這些布局文件才是呈現(xiàn)數(shù)據(jù)的,下面是另外2個布局文件:

layout1:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@drawable/test1"  android:orientation="vertical"  android:id="@+id/container1"  >   <Button  android:id="@+id/bt_towhile"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_gravity="center"  android:text="白色" />  </LinearLayout> 

layout2:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/container2"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@drawable/test2"  android:orientation="vertical" >   <Button  android:id="@+id/bt_toblack"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_gravity="center"  android:text="黑色" />  </LinearLayout> 

我這里只是舉個例子并沒有放什么實際的類容,只是放了2個button,當(dāng)我點擊其中一個跳轉(zhuǎn)到另外一個layout。

有了布局文件那我們就開始要實現(xiàn)功能了,我們的想法是點擊按鈕的時候開始一個動畫等動畫結(jié)束時再開啟另外一個動畫并隱藏和展示layout1和layout2。

下面是我寫的一個動畫工具類源碼:

package com.test.view;  import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.DecelerateInterpolator;  public class RotateAnimationUtil {   private ViewGroup context;   private View[] views;   public RotateAnimationUtil(ViewGroup context, View... views) {  super();  this.context = context;  this.views = views;  }   /**  * 應(yīng)用自定義的Rotate3DAnimation動畫  *  * @param flag  *  當(dāng)前控件的順序坐標(biāo)  * @param startDegress  *  開始的角度  * @param endDegress  *  結(jié)束的角度  */  public void applyRotateAnimation(int flag, float startDegress,   float endDegress) {  final float centerX = context.getWidth() / 2.0f;  final float centerY = context.getHeight() / 2.0f;   Rotate3DAnimation rotate = new Rotate3DAnimation(startDegress,   endDegress, centerX, centerY, 310.0f, true);  rotate.setDuration(1000);  rotate.setFillAfter(false);  rotate.setInterpolator(new DecelerateInterpolator());   rotate.setAnimationListener(new DisplayNextView(flag));  context.startAnimation(rotate);  }   private final class DisplayNextView implements Animation.AnimationListener {   private final int mFlag;   private DisplayNextView(int flag) {   mFlag = flag;  }   public void onAnimationStart(Animation animation) {   }   // 動畫結(jié)束   public void onAnimationEnd(Animation animation) {   context.post(new SwapViews(mFlag));  }   public void onAnimationRepeat(Animation animation) {   }  }   /**  * 新開一個線程動畫結(jié)束后再開始一次動畫效果實現(xiàn)翻屏特效  *  * @author yangzhiqiang  *  */  private final class SwapViews implements Runnable {   private final int mFlag;   public SwapViews(int mFlag) {   this.mFlag = mFlag;  }   public void run() {   final float centerX = context.getWidth() / 2.0f;   final float centerY = context.getHeight() / 2.0f;   Rotate3DAnimation rotation;   if (mFlag > -1) {   views[0].setVisibility(View.GONE);   views[1].setVisibility(View.VISIBLE);   views[1].requestFocus();   rotation = new Rotate3DAnimation(270, 360, centerX, centerY,    310.0f, false);   } else {   views[1].setVisibility(View.GONE);   views[0].setVisibility(View.VISIBLE);   views[0].requestFocus();   rotation = new Rotate3DAnimation(90, 0, centerX, centerY,    310.0f, false);   }   rotation.setDuration(1000);   rotation.setFillAfter(false);   rotation.setInterpolator(new DecelerateInterpolator());   // 開始動畫   context.startAnimation(rotation);   }   }  } 

解釋一下這個類的構(gòu)造方法:

public RotateAnimationUtil(ViewGroup context, View... views) {  super();  this.context = context;  this.views = views;  } 

有2個參數(shù),第一個參數(shù)就是我們的主布局頁面的FrameLayout,第2個參數(shù)就是我們要進(jìn)行動畫切換的2個子layout,我這使用的是一個可變長參數(shù)只是為了方便而已。

public void applyRotateAnimation(int flag, float startDegress,float endDegress)方法第一個參數(shù)是標(biāo)記當(dāng)前是第是從哪個個layout跳轉(zhuǎn),因外我們必須知道當(dāng)前開始跳轉(zhuǎn)的layout才能推算角度。
下面是我自定義動畫的源碼:

package com.test.view;  import android.graphics.Camera; import android.graphics.Matrix; import android.view.animation.Animation; import android.view.animation.Transformation;  public class Rotate3DAnimation extends Animation {   private final float mFormDegress;   private final float mToDegress;   private final float mCenterX;   private final float mCenterY;   /**  * 控制z軸的一個常量值,主要是控制動畫的升降距離  */  private final float mDepthz;   /**  * 控制z軸是像上移動還是向下移動,從而實現(xiàn)升降效果  */  private final boolean mReverse;   private Camera mCamera;   public Rotate3DAnimation(float formDegress, float toDegress, float centerX,   float centerY, float depthz, boolean reverse) {  super();  this.mFormDegress = formDegress;  this.mToDegress = toDegress;  this.mCenterX = centerX;  this.mCenterY = centerY;  this.mDepthz = depthz;  this.mReverse = reverse;  }   @Override  public void initialize(int width, int height, int parentWidth,   int parentHeight) {  super.initialize(width, height, parentWidth, parentHeight);  mCamera = new Camera();  }   /**  * interpolatedTime 取值范圍是0-1之間當(dāng)每次,當(dāng)動畫啟動后會系統(tǒng)會不停的調(diào)用applyTransformation方法,  * 并改變interpolatedTime的值  */  @Override  protected void applyTransformation(float interpolatedTime, Transformation t) {  final float formDegress = mFormDegress;  // 通過差點值計算出轉(zhuǎn)變的角度  float degress = formDegress   + ((mToDegress - formDegress) * interpolatedTime);  final float centerX = mCenterX;  final float centerY = mCenterY;  final Camera camera = mCamera;   // 得到當(dāng)前矩陣  Matrix matrix = t.getMatrix();  // 報錯當(dāng)前屏幕的狀態(tài)  camera.save();  // 判斷是降還是升  if (mReverse) {   // 正向改變Z軸角度   camera.translate(0.0f, 0.0f, mDepthz * interpolatedTime);  } else {   // 反向改變Z軸角度   camera.translate(0.0f, 0.0f, mDepthz * (1.0f - interpolatedTime));  }  // 旋轉(zhuǎn)Y軸角度  camera.rotateY(degress);  // 把當(dāng)前改變后的矩陣信息復(fù)制給Transformation的Matrix  camera.getMatrix(matrix);  // 根據(jù)改變后的矩陣信息從新恢復(fù)屏幕  camera.restore();   // 讓動畫在屏幕中間運行  matrix.preTranslate(-centerX, -centerY);  matrix.postTranslate(centerX, centerY);  } } 

如果你不需要沉降效果那么你把下面的代碼刪除掉即可:

if (mReverse) {   // 正向改變Z軸角度   camera.translate(0.0f, 0.0f, mDepthz * interpolatedTime);  } else {   // 反向改變Z軸角度   camera.translate(0.0f, 0.0f, mDepthz * (1.0f - interpolatedTime));  } 

好了核心代碼已經(jīng)上完,下面是主界面代碼:

package com.test.rotateanimation;  import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; import android.widget.LinearLayout;  import com.test.view.RotateAnimationUtil;  public class MainActivity extends Activity {   private FrameLayout container;   private LinearLayout container1;   private LinearLayout container2;   private RotateAnimationUtil rotateAnimationUtil;   private Button bt_towhile;   private Button bt_toblack;   @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  initView();   bt_towhile.setOnClickListener(new View.OnClickListener() {    @Override   public void onClick(View v) {   rotateAnimationUtil.applyRotateAnimation(1, 0, 90);   }  });  bt_toblack.setOnClickListener(new View.OnClickListener() {    @Override   public void onClick(View v) {   rotateAnimationUtil.applyRotateAnimation(-1, 0, -90);   }  });   // 設(shè)置當(dāng)前View控件的緩存  container   .setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);  }   private void initView() {  container = (FrameLayout) findViewById(R.id.container);  bt_toblack = (Button) findViewById(R.id.bt_toblack);  bt_towhile = (Button) findViewById(R.id.bt_towhile);   container1 = (LinearLayout) findViewById(R.id.container1);  container2 = (LinearLayout) findViewById(R.id.container2);   rotateAnimationUtil = new RotateAnimationUtil(container, container1,   container2);  }   @Override  public boolean onCreateOptionsMenu(Menu menu) {  getMenuInflater().inflate(R.menu.activity_main, menu);  return true;  }  } 

下面是運行效果,剪切效果不好,呵呵.

 源碼下載:http://xiazai.VeVB.COm/201606/yuanma/RotateAnimation(VeVB.COm).rar

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 大余县| 松江区| 唐山市| 岗巴县| 时尚| 宜兴市| 建湖县| 宁陕县| 泽州县| 会东县| 鸡东县| 枝江市| 凤山市| 呼图壁县| 荔浦县| 富民县| 汕头市| 鸡西市| 万宁市| 外汇| 北安市| 安仁县| 娱乐| 新闻| 绿春县| 民乐县| 长丰县| 哈巴河县| 兴仁县| 乐平市| 云和县| 峨边| 冷水江市| 辽阳市| 日土县| 迁西县| 河北省| 武强县| 锡林浩特市| 石门县| 拜城县|