前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android页面中引导蒙层的使用方法详解

Android页面中引导蒙层的使用方法详解

作者头像
砸漏
发布2020-11-04 09:40:04
1.9K0
发布2020-11-04 09:40:04
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本

蒙层是什么,蒙层是一层透明的呈灰色的视图,是在用户使用App时让用户快速学会使用的一些指导。类似于一些引导页面,只不过比引导页面更加生动形象而已。在GitHub上有具体的demo。

地址为github源码地址,需要的可以去上面下载源码看看

使用引导蒙层非常简单,只要在你的项目中导入一个GuideView类即可,当然,别忘了在values的资源文件下加上相应的一些数值。

下面是GuideView的原码

代码语言:javascript
复制
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;
}
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() {
@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;
}
}
}
导入后,在你想要使用蒙层的类中,使用也非常简单
首先我们来初始化一个蒙层
GuideView guideView = GuideView.Builder
.newInstance(this)
.setTargetView(menu)//设置目标
.setCustomGuideView(iv)//设置蒙层上面使用的图片
.setDirction(GuideView.Direction.LEFT_BOTTOM)
.setShape(GuideView.MyShape.CIRCULAR) // 设置圆形显示区域,
.setBgColor(getResources().getColor(R.color.shadow))
.setOnclickListener(new GuideView.OnClickCallback() {
@Override
public void onClickedGuideView() {
guideView.hide();
}
})
.build();

然后 使用guideView.show();方式来展现蒙层,guideView.hide()是让蒙层消失。

效果如图所示:

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档