本文实现了Android中dialog的3D翻转效果。这里通过一个简单的应用场景记录下。
效果图
起初自己的思路是Activity进行界面跳转实现旋转效果,网上看了很多,写下来发现效果不对。之后又看到Google上面的Card Flid Animation效果是这样的。
看着确实不错,然而拿下来demo放慢翻转速度后发现,不是我想要的。但是跟我看到的一个app里面的效果一样 然后想改成dialog试试效果,发现更是不行了。
Card Flid Animation效果如下: 这个是通过Activity来切换Fragment实现的,可以看到区别是翻转时候貌似会变大,其实没用,只是翻转后的视觉问题。
听说openGl比较麻烦,并且没有用过。然后就搜了下Rotate3DAnimaitons。 搜到了这篇文章http://blog.csdn.net/growing_tree/article/details/50428148 所以这篇文章里的实现方法不是我的原创,是参考人家的。在这里感谢这位大神。 不过他这个是activity里的,我就想要一个dialog效果,因为电脑上TIM的打开红包这个3D效果看着不错,其实大同小异,就拿过来改成Dialog。 对于Rotate3DAnimaitons这篇文章已经很详细了,有需要的可以参考下。
这里也贴下Rotate3dAnimation 的代码
简单加了两行注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 public class Rotate3dAnimation extends Animation { private final float mFromDegrees; private final float mToDegrees; private final float mCenterX; private final float mCenterY; private final float mDepthZ; private final boolean mReverse; private Camera mCamera; public Rotate3dAnimation (float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; mReverse = reverse; } @Override public void initialize (int width, int height, int parentWidth, int parentHeight) { super .initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } @Override protected void applyTransformation (float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); Log.i("interpolatedTime" , interpolatedTime+"" ); camera.save(); if (mReverse) { camera.translate(0.0f , 0.0f , mDepthZ * interpolatedTime); } else { camera.translate(0.0f , 0.0f , mDepthZ * (1.0f - interpolatedTime)); } camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } }
dialog实现3D翻转代码,
说明:动画部分的代码是拿的搜的的那篇文章的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 public class MyDialog extends Dialog { @BindView (R.id.et_user_name) EditText etUserName; @BindView (R.id.et_password) EditText etPassword; @BindView (R.id.cb_auto_login) CheckBox cbAutoLogin; @BindView (R.id.tv_forget_pwd) TextView tvForgetPwd; @BindView (R.id.ll_content) LinearLayout llContent; @BindView (R.id.et_email) EditText etEmail; @BindView (R.id.btn_back) Button btnBack; @BindView (R.id.container) RelativeLayout container; private Context context; @BindView (R.id.ll_register) LinearLayout llRegister; private OnClickListenerInterface mListener; private View view; private String strContent; private int centerX; private int centerY; private int depthZ = 700 ; private int duration = 300 ; private Rotate3dAnimation openAnimation; private Rotate3dAnimation closeAnimation; private boolean isOpen = false ; public interface OnClickListenerInterface { void doConfirm () ; } public MyDialog (Context context) { super (context); this .context = context; } public MyDialog (Context context, String content) { super (context); this .context = context; this .strContent = content; } @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); getWindow().setBackgroundDrawableResource(android.R.color.transparent); requestWindowFeature(Window.FEATURE_NO_TITLE); init(); } public void init () { LayoutInflater inflater = LayoutInflater.from(context); view = inflater.inflate(R.layout.dialog_my, null ); setContentView(view); ButterKnife.bind(this ); etPassword.setTypeface(Typeface.DEFAULT); etPassword.setTransformationMethod(new PasswordTransformationMethod()); tvForgetPwd.setOnClickListener(new OnWidgetClickListener()); btnBack.setOnClickListener(new OnWidgetClickListener()); Window dialogWindow = getWindow(); WindowManager.LayoutParams lp = dialogWindow.getAttributes(); DisplayMetrics d = context.getResources().getDisplayMetrics(); lp.width = (int ) (d.widthPixels * 0.8 ); lp.height = (int ) (d.heightPixels * 0.6 ); dialogWindow.setAttributes(lp); setCanceledOnTouchOutside(false ); setCancelable(true ); } public void setClicklistener (OnClickListenerInterface clickListenerInterface) { this .mListener = clickListenerInterface; } private class OnWidgetClickListener implements View .OnClickListener { @Override public void onClick (View v) { int id = v.getId(); switch (id) { case R.id.tv_forget_pwd: startAnimation(); break ; case R.id.btn_back: startAnimation(); break ; } } } private void startAnimation () { centerX = container.getWidth() / 2 ; centerY = container.getHeight() / 2 ; if (openAnimation == null ) { initOpenAnim(); initCloseAnim(); } if (openAnimation.hasStarted() && !openAnimation.hasEnded()) { return ; } if (closeAnimation.hasStarted() && !closeAnimation.hasEnded()) { return ; } if (isOpen) { container.startAnimation(openAnimation); } else { container.startAnimation(closeAnimation); } isOpen = !isOpen; } private void initOpenAnim () { openAnimation = new Rotate3dAnimation(0 , 90 , centerX, centerY, depthZ, true ); openAnimation.setDuration(duration); openAnimation.setFillAfter(true ); openAnimation.setInterpolator(new AccelerateInterpolator()); openAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart (Animation animation) { } @Override public void onAnimationRepeat (Animation animation) { } @Override public void onAnimationEnd (Animation animation) { llRegister.setVisibility(View.GONE); llContent.setVisibility(View.VISIBLE); Rotate3dAnimation rotateAnimation = new Rotate3dAnimation(270 , 360 , centerX, centerY, depthZ, false ); rotateAnimation.setDuration(duration); rotateAnimation.setFillAfter(true ); rotateAnimation.setInterpolator(new DecelerateInterpolator()); container.startAnimation(rotateAnimation); } }); } private void initCloseAnim () { closeAnimation = new Rotate3dAnimation(360 , 270 , centerX, centerY, depthZ, true ); closeAnimation.setDuration(duration); closeAnimation.setFillAfter(true ); closeAnimation.setInterpolator(new AccelerateInterpolator()); closeAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart (Animation animation) { } @Override public void onAnimationRepeat (Animation animation) { } @Override public void onAnimationEnd (Animation animation) { llRegister.setVisibility(View.VISIBLE); llContent.setVisibility(View.GONE); Rotate3dAnimation rotateAnimation = new Rotate3dAnimation(90 , 0 , centerX, centerY, depthZ, false ); rotateAnimation.setDuration(duration); rotateAnimation.setFillAfter(true ); rotateAnimation.setInterpolator(new DecelerateInterpolator()); container.startAnimation(rotateAnimation); } }); } }
关于Flip效果的实现可以参考文章Card Flip Animations的实现 ,
源码中也有Flip效果的实现
说明:上传的Demo全部为免积分,现在CSDN设置最低收了一积分,没办法了。没有积分的可以在github上下载