欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现dialog的3D翻转示例

程序员文章站 2023-11-28 23:40:46
本文实现了android中dialog的3d翻转效果。这里通过一个简单的应用场景记录下。 效果图 起初自己的思路是activity进行界面跳转实现旋转效果,网上...

本文实现了android中dialog的3d翻转效果。这里通过一个简单的应用场景记录下。

效果图

Android实现dialog的3D翻转示例

起初自己的思路是activity进行界面跳转实现旋转效果,网上看了很多,写下来发现效果不对。之后又看到google上面的card flid animation效果是这样的。

Android实现dialog的3D翻转示例

看着确实不错,然而拿下来demo放慢翻转速度后发现,不是我想要的。但是跟我看到的一个app里面的效果一样

然后想改成dialog试试效果,发现更是不行了。

card flid animation效果如下:

这个是通过activity来切换fragment实现的,可以看到区别是翻转时候貌似会变大,其实没用,只是翻转后的视觉问题。

Android实现dialog的3D翻转示例

听说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);
      }
    });
  }
}

demo下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。