当前位置: 移动技术网 > 移动技术>移动开发>Android > Android实现新手引导半透明蒙层效果

Android实现新手引导半透明蒙层效果

2019年07月23日  | 移动技术网移动技术  | 我要评论
本文实例为大家分享了android实现新手引导半透明蒙层效果的具体代码,供大家参考,具体内容如下 效果图: 其中的文字和我知道啦是ui切得两张透明图片

本文实例为大家分享了android实现新手引导半透明蒙层效果的具体代码,供大家参考,具体内容如下

效果图:


其中的文字和我知道啦是ui切得两张透明图片

自定义view:

package com.cymobi.library.view.widget;

import android.app.activity;
import android.content.context;
import android.graphics.bitmap;
import android.graphics.canvas;
import android.graphics.paint;
import android.graphics.porterduff;
import android.graphics.porterduffxfermode;
import android.graphics.rectf;
import android.util.log;
import android.view.gravity;
import android.view.view;
import android.view.viewgroup;
import android.view.viewtreeobserver;
import android.widget.framelayout;
import android.widget.relativelayout;

import com.cymobi.library.r;

/**
 * created by xuke on 2017/8/24.
 */

public class guideview extends relativelayout implements viewtreeobserver.ongloballayoutlistener {
  private final string tag = getclass().getsimplename();
  private context mcontent;
  private boolean first = true;
  private static final string show_guide_prefix = "show_guide";
  private int offsetx, offsety;
  private int radius;
  private view targetview;
  private view textguideview;
  private view customguideview;
  private paint mcirclepaint;
  private paint mbackgroundpaint;
  private boolean ismeasured;
  private int[] center;
  private porterduffxfermode porterduffxfermode;
  private bitmap bitmap;
  private int backgroundcolor;
  private canvas temp;
  private direction direction;
  private myshape myshape;
  private int[] location;
  private boolean onclickexit;
  private onclickcallback onclicklistener;
  private int targetviewwidth;
  private int targetviewheight;
  private boolean iscontain = false;
  private boolean needdraw = true;


  public guideview(context context) {
    super(context);
    this.mcontent = context;
  }

  public int[] getlocation() {
    return location;
  }

  public void setlocation(int[] location) {
    this.location = location;
  }

  public int getradius() {
    return radius;
  }

  public void setradius(int radius) {
    this.radius = radius;
  }

  public void setdirection(direction direction) {
    this.direction = direction;
  }

  public void setshape(myshape shape) {
    this.myshape = shape;
  }

  public void setbgcolor(int background_color) {
    this.backgroundcolor = background_color;
  }

  public void settargetview(view targetview) {
    this.targetview = targetview;
  }

  public int[] getcenter() {
    return center;
  }

  public void setcenter(int[] center) {
    this.center = center;
  }

  public void setoffsetx(int offsetx) {
    this.offsetx = offsetx;
  }

  public void setoffsety(int offsety) {
    this.offsety = offsety;
  }

  public void setcontain(boolean contain) {
    this.iscontain = contain;
  }

  public void setcustomguideview(view customguideview) {
    this.customguideview = customguideview;
    if (!first) {
      restorestate();
    }
  }

  public void settextguideview(view textguideview) {
    this.textguideview = textguideview;
    if (!first) {
      restorestate();
    }
  }

  private boolean hasshown() {
    if (targetview == null)
      return true;
    return mcontent.getsharedpreferences(tag, context.mode_private).getboolean(generateuniqid(targetview), false);
  }

  private string generateuniqid(view v) {
    return show_guide_prefix + v.getid();
  }

  public void setonclicklistener(onclickcallback onclicklistener) {
    this.onclicklistener = onclicklistener;
  }

  private void setclickinfo() {
    final boolean exit = onclickexit;
    setonclicklistener(new onclicklistener() {
      @override
      public void onclick(view v) {
        if (onclicklistener != null) {
          onclicklistener.onclickedguideview();
        }
        if (exit) {
          hide();
        }
      }
    });
  }

  public void show() {
    log.v(tag, "show");
    if (hasshown())
      return;

    if (targetview != null) {
      targetview.getviewtreeobserver().addongloballayoutlistener(this);
    }

    this.setbackgroundresource(r.color.transparent);
    this.bringtofront(); //设置在最上层
    ((framelayout) ((activity) mcontent).getwindow().getdecorview()).addview(this);
    first = false;
  }

  public void hide() {
    log.v(tag, "hide");
    if (customguideview != null || textguideview != null) {
      targetview.getviewtreeobserver().removeongloballayoutlistener(this);
      this.removeallviews();
      ((framelayout) ((activity) mcontent).getwindow().getdecorview()).removeview(this);
      restorestate();
    }
  }

  /**
   * 获得targetview 的宽高
   *
   * @return
   */
  private int[] gettargetviewsize() {
    int[] location = {-1, -1};
    if (ismeasured) {
      location[0] = targetview.getwidth();
      location[1] = targetview.getheight();
    }
    return location;
  }

  /**
   * 获得targetview 的半径
   *
   * @return
   */
  private int gettargetviewradius() {
    if (ismeasured) {
      int[] size = gettargetviewsize();
      int x = size[0];
      int y = size[1];

      return (int) (math.sqrt(x * x + y * y) / 2);
    }
    return -1;
  }

  @override
  protected void ondraw(canvas canvas) {
    super.ondraw(canvas);
    log.v(tag, "ondraw");
    if (!ismeasured)
      return;
    if (targetview == null)
      return;
    drawbackground(canvas);
  }


  private void drawbackground(canvas canvas) {
    log.v(tag, "drawbackground");
    needdraw = false;
    // 先绘制bitmap,再将bitmap绘制到屏幕
    bitmap = bitmap.createbitmap(canvas.getwidth(), canvas.getheight(), bitmap.config.argb_8888);
    temp = new canvas(bitmap);

    // 背景画笔
    paint bgpaint = new paint();
    if (backgroundcolor != 0) {
      bgpaint.setcolor(backgroundcolor);
    } else {
      bgpaint.setcolor(getresources().getcolor(r.color.bg_shadow));
    }
    // 绘制屏幕背景
    temp.drawrect(0, 0, temp.getwidth(), temp.getheight(), bgpaint);

    // targetview 的透明圆形画笔
    if (mcirclepaint == null) {
      mcirclepaint = new paint();
    }
    //透明效果
    porterduffxfermode = new porterduffxfermode(porterduff.mode.clear);  //src_out或者clear都可以
    mcirclepaint.setxfermode(porterduffxfermode);
    mcirclepaint.setantialias(true);

    if (myshape != null) {
      rectf oval = new rectf();
      switch (myshape) {
        case circular://圆形
          temp.drawcircle(center[0], center[1], radius, mcirclepaint);
          break;
        case rectangular://圆角矩形
          if (iscontain) {
            oval.left = location[0] - 8;
            oval.top = center[1] - targetviewheight / 2 - 8;
            oval.right = location[0] + targetviewwidth + 8;
            oval.bottom = center[1] + targetviewheight / 2 + 8;
          } else {
            oval.left = location[0] + 5;
            oval.top = center[1] - targetviewheight / 2 + 1;
            oval.right = location[0] + targetviewwidth - 5;
            oval.bottom = center[1] + targetviewheight / 2 - 1;
          }
          temp.drawroundrect(oval, radius, radius, mcirclepaint);
          break;
      }
    } else {
      temp.drawcircle(center[0], center[1], radius, mcirclepaint);
    }

    // 绘制到屏幕
    canvas.drawbitmap(bitmap, 0, 0, bgpaint);
    bitmap.recycle();
  }




  @override
  public void ongloballayout() {
    if (ismeasured)
      return;
    if (targetview.getheight() > 0 && targetview.getwidth() > 0) {
      ismeasured = true;
      targetviewwidth = targetview.getwidth();
      targetviewheight = targetview.getheight();
    }

    // 获取targetview的中心坐标
    if (center == null) {
      // 获取右上角坐标
      location = new int[2];
      targetview.getlocationinwindow(location);
      center = new int[2];
      // 获取中心坐标
      center[0] = location[0] + targetview.getwidth() / 2;
      center[1] = location[1] + targetview.getheight() / 2;
    }
    // 获取targetview外切圆半径
    if (radius == 0) {
      radius = gettargetviewradius();
    }

    //文字图片和提示图片
    createview();

  }

  //文字图片和我知道啦图片一起放
  private void createview() {
    log.v(tag, "createview");

    //文字提示
    layoutparams textviewparams;
    textviewparams = new layoutparams(layoutparams.match_parent, layoutparams.wrap_content);
    textviewparams.setmargins(0, center[1] + radius + 10, 0, 0);

    // 我知道提示布局参数
    layoutparams guideviewparams;
    guideviewparams = new layoutparams(layoutparams.match_parent, layoutparams.wrap_content);
    guideviewparams.setmargins(0, center[1] + radius + 10, 0, 0);

    if (textguideview != null && customguideview != null) {
      if (direction != null) {
        int left = center[0] + targetviewwidth / 2;
        int right = center[0] + targetviewwidth / 2;
        int top = center[1] - targetviewheight / 2;
        int bottom = center[1] + targetviewheight / 2;

        //我自己的项目只需要这两个方向的, 所以这里就只写了top和boottom
        switch (direction) {
          case top:
            this.setgravity(gravity.center_horizontal);
            textviewparams.setmargins(offsetx, top - offsety, -offsetx, -top + offsety);
            guideviewparams.setmargins(offsetx, -3 * offsety + top, -offsetx, -top + 3 * offsety);
            break;
          case bottom:
            this.setgravity(gravity.center_horizontal);
            textviewparams.setmargins(offsetx, bottom + offsety, -offsetx, -bottom - offsety);
            guideviewparams.setmargins(offsetx, bottom + 3 * offsety, -offsetx, -bottom - 3 * offsety);
            break;
        }

        if (this != null)
          this.removeallviews();
        this.addview(textguideview, textviewparams);
        this.addview(customguideview, guideviewparams);
      }
    }
  }


  /**
   * 定义guideview相对于targetview的方位,
   */
  public enum direction {
    left, top, right, bottom,
    left_top, left_bottom,
    right_top, right_bottom
  }

  /**
   * 定义目标控件的形状。圆形,矩形
   */
  public enum myshape {
    circular, rectangular
  }

  /**
   * guideview点击callback
   */
  public interface onclickcallback {
    void onclickedguideview();
  }

  public static class builder {
    static guideview guiderview;
    static builder instance = new builder();
    context mcontext;

    private builder() {
    }

    public builder(context ctx) {
      mcontext = ctx;
    }

    public static builder newinstance(context ctx) {
      guiderview = new guideview(ctx);
      return instance;
    }

    /**
     * 设置目标view
     */
    public builder settargetview(view target) {
      guiderview.settargetview(target);
      return instance;
    }

    /**
     * 设置蒙层颜色
     */
    public builder setbgcolor(int color) {
      guiderview.setbgcolor(color);
      return instance;
    }

    /**
     * 设置文字和图片view 在目标view的位置
     */
    public builder setdirction(direction dir) {
      guiderview.setdirection(dir);
      return instance;
    }

    /**
     * 设置绘制形状
     */
    public builder setshape(myshape shape) {
      guiderview.setshape(shape);
      return instance;
    }

    public builder setradius(int radius) {
      guiderview.setradius(radius);
      return instance;
    }

    /**
     * 设置文字图片
     */
    public builder settextguideview(view view) {
      guiderview.settextguideview(view);
      return instance;
    }

    /**
     * 设置"我知道啦"图片
     */
    public builder setcustomguideview(view view) {
      guiderview.setcustomguideview(view);
      return instance;
    }

    /**
     * 设置图片的偏移量
     */
    public builder setoffset(int x, int y) {
      guiderview.setoffsetx(x);
      guiderview.setoffsety(y);
      return instance;
    }

    /**
     * 设置时候包含 true:画的透明包含目标view
     */
    public builder setcontain(boolean iscontain) {
      guiderview.setcontain(iscontain);
      return instance;
    }

    /**
     * 点击监听
     */
    public builder setonclicklistener(final onclickcallback callback) {
      guiderview.setonclicklistener(callback);
      return instance;
    }

    public guideview build() {
      guiderview.setclickinfo();
      return guiderview;
    }

  }

  public void restorestate() {
    log.v(tag, "restorestate");
    offsetx = offsety = 0;
    radius = 0;
    mcirclepaint = null;
    mbackgroundpaint = null;
    ismeasured = false;
    center = null;
    porterduffxfermode = null;
    bitmap = null;
    needdraw = true;
    temp = null;
  }
}

在自己页面应用:

//文字图片
    final imageview iv1 = new imageview(context);
    iv1.setimageresource(r.drawable.img_guide_work_text);
    relativelayout.layoutparams params1 = new relativelayout.layoutparams(viewgroup.layoutparams.wrap_content, viewgroup.layoutparams.wrap_content);
    iv1.setlayoutparams(params1);

    //我知道啦
    final imageview iv2 = new imageview(context);
    iv2.setimageresource(r.drawable.img_guide_know);
    relativelayout.layoutparams params2 = new relativelayout.layoutparams(viewgroup.layoutparams.wrap_content, viewgroup.layoutparams.wrap_content);
    iv2.setlayoutparams(params2);

 guideview = guideview.builder
        .newinstance(context)
        .settargetview(itemwork) //设置目标view
        .settextguideview(iv1)   //设置文字图片
        .setcustomguideview(iv2)  //设置 我知道啦图片
        .setoffset(0, 80)      //偏移量 x=0 y=80
        .setdirction(guideview.direction.bottom)  //方向
        .setshape(guideview.myshape.rectangular)  //矩形
        .setradius(10)               //圆角
        .setcontain(false)             //透明的方块时候包含目标view 默认false
        .setbgcolor(getresources().getcolor(r.color.bg_shadow))  //背景颜色
        .setonclicklistener(new guideview.onclickcallback() {
          @override
          public void onclickedguideview() {
            guideview.hide();
          }
        })
        .build();
guideview.show();


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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网