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

Android利用动画实现背景逐渐变暗

程序员文章站 2024-02-25 18:38:21
前言 之前写了一篇android-实现底部弹出popupwindow并让背景逐渐变暗,介绍利用handler动态改变背景透明度从而达到变暗的效果。现在补充一种方法,使用动...

前言

之前写了一篇android-实现底部弹出popupwindow并让背景逐渐变暗,介绍利用handler动态改变背景透明度从而达到变暗的效果。现在补充一种方法,使用动画来实现相同的效果。

valueanimator interpolator

今天的主角就是这俩,关于valueanimator和interpolator(插值器)的概念请各位自行补充,这里主要讲述怎么用到我们这里来(因为我也不很懂(捂脸))。

效果

跟之前没有太大区别,只是为了演示变暗、变亮的过程 ↓

Android利用动画实现背景逐渐变暗

代码

animutil.java

/**
 * 动画工具类
 * updatelistener: 动画过程中通过添加此监听来回调数据
 * endlistener: 动画结束的时候通过此监听器来做一些处理
 */
public class animutil {

  private valueanimator valueanimator;
  private updatelistener updatelistener;
  private endlistener endlistener;
  private long duration;
  private float start;
  private float end;
  private interpolator interpolator = new linearinterpolator();

  public animutil() {
    duration = 1000; //默认动画时常1s
    start = 0.0f;
    end = 1.0f;
    interpolator = new linearinterpolator();// 匀速的插值器
  }


  public void setduration(int timelength) {
    duration = timelength;
  }

  public void setvalueanimator(float start, float end, long duration) {

    this.start = start;
    this.end = end;
    this.duration = duration;

  }

  public void setinterpolator(interpolator interpolator) {
    this.interpolator = interpolator;
  }

  public void startanimator() {
    if (valueanimator != null){
      valueanimator = null;
    }
    valueanimator = valueanimator.offloat(start, end);
    valueanimator.setduration(duration);
    valueanimator.setinterpolator(interpolator);
    valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() {
      @override
      public void onanimationupdate(valueanimator valueanimator) {

        if (updatelistener == null) {
          return;
        }

        float cur = (float) valueanimator.getanimatedvalue();
        updatelistener.progress(cur);
      }
    });
    valueanimator.addlistener(new animator.animatorlistener() {
      @override
      public void onanimationstart(animator animator) {}
      @override
      public void onanimationend(animator animator) {
        if(endlistener == null){
          return;
        }
        endlistener.endupdate(animator);
      }
      @override
      public void onanimationcancel(animator animator) {}

      @override
      public void onanimationrepeat(animator animator) {}
    });
    valueanimator.start();
  }

  public void addupdatelistener(updatelistener updatelistener) {

    this.updatelistener = updatelistener;
  }

  public void addendlistner(endlistener endlistener){
    this.endlistener = endlistener;
  }

  public interface endlistener {
    void endupdate(animator animator);
  }

  public interface updatelistener {

    void progress(float progress);
  }

}

mainactivity.java

public class mainactivity extends appcompatactivity {
  private animutil animutil;
  private float bgalpha = 1f;
  private boolean bright = false;
  popupwindow popupwindow;
  button button;
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    animutil = new animutil();
    button = (button) findviewbyid(r.id.btn);
    button.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view view) {
        bottomwindow(button);
        togglebright();
      }
    });

  }

  private void togglebright() {
    //三个参数分别为: 起始值 结束值 时长 那么整个动画回调过来的值就是从0.5f--1f的
    animutil.setvalueanimator(0.5f, 1f, 350);
    animutil.addupdatelistener(new animutil.updatelistener() {
      @override
      public void progress(float progress) {
        //此处系统会根据上述三个值,计算每次回调的值是多少,我们根据这个值来改变透明度
        bgalpha = bright ? progress : (1.5f - progress);//三目运算,应该挺好懂的。
        backgroundalpha(bgalpha);//在此处改变背景,这样就不用通过handler去刷新了。
      }
    });
    animutil.addendlistner(new animutil.endlistener() {
      @override
      public void endupdate(animator animator) {
        //在一次动画结束的时候,翻转状态
        bright = !bright;
      }
    });
    animutil.startanimator();
  }

  /***
   * 此方法用于改变背景的透明度,从而达到“变暗”的效果
   */
  private void backgroundalpha(float bgalpha) {
    windowmanager.layoutparams lp = getwindow().getattributes();
    lp.alpha = bgalpha; //0.0-1.0
    getwindow().setattributes(lp);
    getwindow().addflags(windowmanager.layoutparams.flag_dim_behind);
  }


  void bottomwindow(view view) {
    if (popupwindow != null && popupwindow.isshowing()) {
      return;
    }
    linearlayout layout = (linearlayout) getlayoutinflater().inflate(r.layout.window_popup, null);
    popupwindow = new popupwindow(layout,
        viewgroup.layoutparams.match_parent,
        viewgroup.layoutparams.wrap_content);
    //点击空白处时,隐藏掉pop窗口
    popupwindow.setfocusable(true);
    popupwindow.setbackgrounddrawable(new bitmapdrawable());

    popupwindow.setanimationstyle(r.style.popupwindow);
    int[] location = new int[2];
    view.getlocationonscreen(location);
    popupwindow.showatlocation(view, gravity.left | gravity.bottom, 0, -location[1]);
    popupwindow.setondismisslistener(new popupwindow.ondismisslistener() {
      @override
      public void ondismiss() {
        togglebright();
      }
    });
  }
}

代码很简单,注释都写了。

小结:

对比之前的那种用handler的方法写的,这种感觉代码更简洁,更容易在多处使用,也算是填坑吧,哈哈。 如果本文埋下了另一个坑,请大家指正,谢谢!

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