GuideView的封装实现app功能引导页
程序员文章站
2022-11-14 10:55:42
本文实例为大家分享了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; } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 家有2岁小萝莉一枚
下一篇: iOS仿抖音视频加载动画效果的实现方法