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

GuideView的封装实现app功能引导页

程序员文章站 2022-05-15 15:26:12
本文实例为大家分享了guideview的封装实现app功能引导页的具体代码,供大家参考,具体内容如下 package oschina.comxianbing100...

本文实例为大家分享了guideview的封装实现app功能引导页的具体代码,供大家参考,具体内容如下

package oschina.comxianbing100.yindao;
 
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.os.build;
import android.support.annotation.requiresapi;
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 java.util.list;
 
/**
 * author : majunbao
 * date : 2019/3/4 16:32
 * description :app第一次打开功能蒙版 引导
 */
public class guideview extends relativelayout implements viewtreeobserver.ongloballayoutlistener {
 private final string tag = getclass().getsimplename();
 private context mcontent;
 private list<view> mviews;
 private boolean first = true;
 /**
  * targetview前缀。show_guide_prefix + targetview.getid()作为保存在sp文件的key。
  */
 private static final string show_guide_prefix = "show_guide_on_view_";
 /**
  * guideview 偏移量
  */
 private int offsetx, offsety;
 /**
  * targetview 的外切圆半径
  */
 private int radius;
 /**
  * 需要显示提示信息的view
  */
 private view targetview;
 /**
  * 自定义view
  */
 private view customguideview;
 /**
  * 透明圆形画笔
  */
 private paint mcirclepaint;
 /**
  * 背景色画笔
  */
 private paint mbackgroundpaint;
 /**
  * targetview是否已测量
  */
 private boolean ismeasured;
 /**
  * targetview圆心
  */
 private int[] center;
 /**
  * 绘图层叠模式
  */
 private porterduffxfermode porterduffxfermode;
 /**
  * 绘制前景bitmap
  */
 private bitmap bitmap;
 /**
  * 背景色和透明度,格式 #aarrggbb
  */
 private int backgroundcolor;
 /**
  * canvas,绘制bitmap
  */
 private canvas temp;
 /**
  * 相对于targetview的位置.在target的那个方向
  */
 private direction direction;
 
 /**
  * 形状
  */
 private myshape myshape;
 /**
  * targetview左上角坐标
  */
 private int[] location;
 private boolean onclickexit;
 private onclickcallback onclicklistener;
 private relativelayout guideviewlayout;
 
 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;
  //  backgroundcolor = color.parsecolor("#00000000");
  temp = null;
  //  direction = null;
 
 }
 
 public int[] getlocation() {
  return location;
 }
 
 public void setlocation(int[] location) {
  this.location = location;
 }
 
 public guideview(context context) {
  super(context);
  this.mcontent = context;
  init();
 }
 
 public int getradius() {
  return radius;
 }
 
 public void setradius(int radius) {
  this.radius = radius;
 }
 
 public void setoffsetx(int offsetx) {
  this.offsetx = offsetx;
 }
 
 public void setoffsety(int offsety) {
  this.offsety = offsety;
 }
 
 public void setdirection(direction direction) {
  this.direction = direction;
 }
 
 public void setshape(myshape shape) {
  this.myshape = shape;
 }
 
 public void setcustomguideview(view customguideview) {
  this.customguideview = customguideview;
  if (!first) {
   restorestate();
  }
 }
 
 public void setbgcolor(int background_color) {
  this.backgroundcolor = background_color;
 }
 
 public view gettargetview() {
  return targetview;
 }
 
 public void settargetview(view targetview) {
  this.targetview = targetview;
  //  restorestate();
  if (!first) {
   //   guideviewlayout.removeallviews();
  }
 }
 
 private void init() {
 }
 
 public void showonce() {
  if (targetview != null) {
   mcontent.getsharedpreferences(tag, context.mode_private).edit().putboolean(generateuniqid(targetview), true).commit();
  }
 }
 
 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 int[] getcenter() {
  return center;
 }
 
 public void setcenter(int[] center) {
  this.center = center;
 }
 
 @requiresapi(api = build.version_codes.jelly_bean)
 public void hide() {
  log.v(tag, "hide");
  if (customguideview != null) {
   targetview.getviewtreeobserver().removeongloballayoutlistener(this);
   this.removeallviews();
   ((framelayout) ((activity) mcontent).getwindow().getdecorview()).removeview(this);
   restorestate();
  }
 }
 
 public void show() {
  log.v(tag, "show");
  if (hasshown())
   return;
 
  if (targetview != null) {
   targetview.getviewtreeobserver().addongloballayoutlistener(this);
  }
 
  this.setbackgroundresource(r.color.transparent);
 
  ((framelayout) ((activity) mcontent).getwindow().getdecorview()).addview(this);
  first = false;
 }
 
 /**
  * 添加提示文字,位置在targetview的下边
  * 在屏幕窗口,添加蒙层,蒙层绘制总背景和透明圆形,圆形下边绘制说明文字
  */
 private void createguideview() {
  log.v(tag, "createguideview");
 
  // 添加到蒙层
  //  if (guideviewlayout == null) {
  //   guideviewlayout = new relativelayout(mcontent);
  //  }
 
  // tips布局参数
  layoutparams guideviewparams;
  guideviewparams = new layoutparams(layoutparams.wrap_content, layoutparams.wrap_content);
  guideviewparams.setmargins(0, center[1] + radius + 10, 0, 0);
 
  if (customguideview != null) {
 
   //   layoutparams guideviewparams = new layoutparams(viewgroup.layoutparams.match_parent, viewgroup.layoutparams.wrap_content);
   if (direction != null) {
    int width = this.getwidth();
    int height = this.getheight();
 
    int left = center[0] - radius;
    int right = center[0] + radius;
    int top = center[1] - radius;
    int bottom = center[1] + radius;
    switch (direction) {
     case top:
      this.setgravity(gravity.bottom | gravity.center_horizontal);
      guideviewparams.setmargins(offsetx, offsety - height + top, -offsetx, height - top - offsety);
      break;
     case left:
      this.setgravity(gravity.right);
      guideviewparams.setmargins(offsetx - width + left, top + offsety, width - left - offsetx, -top - offsety);
      break;
     case bottom:
      this.setgravity(gravity.center_horizontal);
      guideviewparams.setmargins(offsetx, bottom + offsety, -offsetx, -bottom - offsety);
      break;
     case right:
      guideviewparams.setmargins(right + offsetx, top + offsety, -right - offsetx, -top - offsety);
      break;
     case left_top:
      this.setgravity(gravity.right | gravity.bottom);
      guideviewparams.setmargins(offsetx - width + left, offsety - height + top, width - left - offsetx, height - top - offsety);
      break;
     case left_bottom:
      this.setgravity(gravity.right);
      guideviewparams.setmargins(offsetx - width + left, bottom + offsety, width - left - offsetx, -bottom - offsety);
      break;
     case right_top:
      this.setgravity(gravity.bottom);
      guideviewparams.setmargins(right + offsetx, offsety - height + top, -right - offsetx, height - top - offsety);
      break;
     case right_bottom:
      guideviewparams.setmargins(right + offsetx, bottom + offsety, -right - offsetx, -top - offsety);
      break;
    }
   } else {
    guideviewparams = new layoutparams(viewgroup.layoutparams.wrap_content, viewgroup.layoutparams.wrap_content);
    guideviewparams.setmargins(offsetx, offsety, -offsetx, -offsety);
   }
 
   //   guideviewlayout.addview(customguideview);
 
   this.addview(customguideview, guideviewparams);
  }
 }
 
 /**
  * 获得targetview 的宽高,如果未测量,返回{-1, -1}
  *
  * @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;
 }
 
 boolean needdraw = true;
 
 @override
 protected void ondraw(canvas canvas) {
  super.ondraw(canvas);
  log.v(tag, "ondraw");
 
  if (!ismeasured)
   return;
 
  if (targetview == null)
   return;
 
  //  if (!needdraw) 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.shadow));
 
  // 绘制屏幕背景
  temp.drawrect(0, 0, temp.getwidth(), temp.getheight(), bgpaint);
 
  // targetview 的透明圆形画笔
  if (mcirclepaint == null)
   mcirclepaint = new paint();
  porterduffxfermode = new porterduffxfermode(porterduff.mode.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 ellipse://椭圆
     //rectf对象
     oval.left = center[0] - 150;        //左边
     oval.top = center[1] - 50;         //上边
     oval.right = center[0] + 150;        //右边
     oval.bottom = center[1] + 50;        //下边
     temp.drawoval(oval, mcirclepaint);     //绘制椭圆
     break;
    case rectangular://圆角矩形
     //rectf对象
     oval.left = center[0] - 150;        //左边
     oval.top = center[1] - 50;         //上边
     oval.right = center[0] + 150;        //右边
     oval.bottom = center[1] + 50;        //下边
     temp.drawroundrect(oval, radius, radius, mcirclepaint);     //绘制圆角矩形
     break;
   }
  } else {
   temp.drawcircle(center[0], center[1], radius, mcirclepaint);//绘制圆形
  }
 
  // 绘制到屏幕
  canvas.drawbitmap(bitmap, 0, 0, bgpaint);
  bitmap.recycle();
 }
 
 public void setonclickexit(boolean onclickexit) {
  this.onclickexit = onclickexit;
 }
 
 public void setonclicklistener(onclickcallback onclicklistener) {
  this.onclicklistener = onclicklistener;
 }
 
 private void setclickinfo() {
  final boolean exit = onclickexit;
  setonclicklistener(new onclicklistener() {
   @requiresapi(api = build.version_codes.jelly_bean)
   @override
   public void onclick(view v) {
    if (onclicklistener != null) {
     onclicklistener.onclickedguideview();
    }
    if (exit) {
     hide();
    }
   }
  });
 }
 
 @override
 public void ongloballayout() {
  if (ismeasured)
   return;
  if (targetview.getheight() > 0 && targetview.getwidth() > 0) {
   ismeasured = true;
  }
 
  // 获取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();
  }
  // 添加guideview
  createguideview();
 }
 
 /**
  * 定义guideview相对于targetview的方位,共八种。不设置则默认在targetview下方
  */
 enum direction {
  left, top, right, bottom,
  left_top, left_bottom,
  right_top, right_bottom
 }
 
 /**
  * 定义目标控件的形状,共3种。圆形,椭圆,带圆角的矩形(可以设置圆角大小),不设置则默认是圆形
  */
 enum myshape {
  circular, ellipse, rectangular
 }
 
 /**
  * guideview点击callback
  */
 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;
  }
 
  public builder settargetview(view target) {
   guiderview.settargetview(target);
   return instance;
  }
 
  public builder setbgcolor(int color) {
   guiderview.setbgcolor(color);
   return instance;
  }
 
  public builder setdirction(direction dir) {
   guiderview.setdirection(dir);
   return instance;
  }
 
  public builder setshape(myshape shape) {
   guiderview.setshape(shape);
   return instance;
  }
 
  public builder setoffset(int x, int y) {
   guiderview.setoffsetx(x);
   guiderview.setoffsety(y);
   return instance;
  }
 
  public builder setradius(int radius) {
   guiderview.setradius(radius);
   return instance;
  }
 
  public builder setcustomguideview(view view) {
   guiderview.setcustomguideview(view);
   return instance;
  }
 
  public builder setcenter(int x, int y) {
   guiderview.setcenter(new int[]{x, y});
   return instance;
  }
 
  public builder showonce() {
   guiderview.showonce();
   return instance;
  }
 
  public guideview build() {
   guiderview.setclickinfo();
   return guiderview;
  }
 
  public builder setonclickexit(boolean onclickexit) {
   guiderview.setonclickexit(onclickexit);
   return instance;
  }
 
  public builder setonclicklistener(final onclickcallback callback) {
   guiderview.setonclicklistener(callback);
   return instance;
  }
 }
}

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