Android实现新手引导半透明蒙层效果
程序员文章站
2022-05-15 15:19:45
本文实例为大家分享了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();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。