Android实现dialog的3D翻转示例
程序员文章站
2023-11-28 23:40:46
本文实现了android中dialog的3d翻转效果。这里通过一个简单的应用场景记录下。
效果图
起初自己的思路是activity进行界面跳转实现旋转效果,网上...
本文实现了android中dialog的3d翻转效果。这里通过一个简单的应用场景记录下。
效果图
起初自己的思路是activity进行界面跳转实现旋转效果,网上看了很多,写下来发现效果不对。之后又看到google上面的card flid animation效果是这样的。
看着确实不错,然而拿下来demo放慢翻转速度后发现,不是我想要的。但是跟我看到的一个app里面的效果一样
然后想改成dialog试试效果,发现更是不行了。
card flid animation效果如下:
这个是通过activity来切换fragment实现的,可以看到区别是翻转时候貌似会变大,其实没用,只是翻转后的视觉问题。
听说opengl比较麻烦,并且没有用过。然后就搜了下rotate3danimaitons。
搜到了这篇文章
所以这篇文章里的实现方法不是我的原创,是参考人家的。在这里感谢这位大神。
不过他这个是activity里的,我就想要一个dialog效果,因为电脑上tim的打开红包这个3d效果看着不错,其实大同小异,就拿过来改成dialog。
对于rotate3danimaitons这篇文章已经很详细了,有需要的可以参考下。
这里也贴下rotate3danimation 的代码
简单加了两行注释
/** * an animation that rotates the view on the y axis between two specified angles. * this animation also adds a translation on the z axis (depth) to improve the effect. */ 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; /** * creates a new 3d rotation on the y axis. the rotation is defined by its * start angle and its end angle. both angles are in degrees. the rotation * is performed around a center point on the 2d space, definied by a pair * of x and y coordinates, called centerx and centery. when the animation * starts, a translation on the z axis (depth) is performed. the length * of the translation can be specified, as well as whether the translation * should be reversed in time. * * @param fromdegrees the start angle of the 3d rotation //起始角度 * @param todegrees the end angle of the 3d rotation //结束角度 * @param centerx the x center of the 3d rotation //x中轴线 * @param centery the y center of the 3d rotation //y中轴线 * @param reverse true if the translation should be reversed, false otherwise//是否反转 */ public rotate3danimation(float fromdegrees, float todegrees, float centerx, float centery, float depthz, boolean reverse) { mfromdegrees = fromdegrees; mtodegrees = todegrees; mcenterx = centerx; mcentery = centery; mdepthz = depthz;//z轴移动的距离,这个来影响视觉效果,可以解决flip animation那个给人看似放大的效果 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翻转代码,
说明:动画部分的代码是拿的搜的的那篇文章的
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 void docancel(); } 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); // 宽度设置为屏幕的0.8 lp.height = (int) (d.heightpixels * 0.6); // 高度设置为屏幕的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() { //从0到90度,顺时针旋转视图,此时reverse参数为true,达到90度时动画结束时视图变得不可见, 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); //从270到360度,顺时针旋转视图,此时reverse参数为false,达到360度动画结束时视图变得可见 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); } }); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。