Android——新手指引 指定View高光显示自定义控件
16lz
2022-01-15
效果图 - 文字没有调偏移量,可自行调整位置偏移setHintTextOffsetXY(x, y)
调用方式
uhv_user_hint.setHeightLightView(heightLightView) //设置高光显示的view .setHeightLightType(UserHintView.DrawHeightLightType.CUSTOM_ROUND_RECT) //设置高光类型为 自定义圆角 .setRectRoundCustom(0, 0, 0, 0) //高光类型为自定义圆角时,四个角的round 单位dp .setHintBackgroundColor(Color.parseColor("#88000000")) //设置背景颜色 //.setHeightLightType(UserHintView.DrawHeightLightType.ROUND_RECT) //设置高光类型为 圆角矩形 //.setRectRound(5) //设置圆角矩形的角度 单位dp //.setHeightLightType(UserHintView.DrawHeightLightType.CIRCLE) //设置高光类型为 圆形 //.setHeightLightType(UserHintView.DrawHeightLightType.RECT) //设置高光类型为 矩形 .setHeightLightExpendSize(2) // 设置高光扩张大小 自定义圆角矩形无效 单位dp .setArrowBitmap(BitmapFactory.decodeResource(context.getResources(), res)) //设置箭头提示图片Bitmap .setArrowSize(150, 150) // 设置图片的大小 单位dp .setDrawHintDirection(UserHintView.DrawHintDirection.LEFT) // 设置提示图片的位置 .setArrowOffsetXY(x, y) //设置图片 X Y轴的偏移量 单位dp .setHintText("测试测试测\n测试测试测") //设置提示文字 .setHintTextColor(Color.WHITE) //设置提示文字的颜色 .setHintTextSize(17) //设置提示文字的大小 单位dp .setHintTextOffsetXY(10, 10) //设置提示文字的 X Y轴的偏移量 单位dp .create();
如果是在AlertDialog中使用,取消AlertDialog半透明背景的方法
private void setStyle() { //去除半透明阴影 WindowManager.LayoutParams layoutParams = getWindow().getAttributes(); layoutParams.dimAmount = 0.0f; getWindow().setAttributes(layoutParams); }@Override public void show() { super.show(); setStyle(); }
注意:在onCreate中调用的话,需要监听view的可视化状态变更事件,在该监听中去使用
例:
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ... view.getViewTreeObserver().removeOnGlobalLayoutListener(this); } });//在recyclerView 中的itemrv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //获取对应itemView View view = rv.getLayoutManager().findViewByPosition(0); //获取对应item中的某个view //view.findViewById(R.id.tv); rv.getViewTreeObserver().removeOnGlobalLayoutListener(this); } });
枚举类型:
//绘制高亮类型 private DrawHeightLightType mHeightLightType = DrawHeightLightType.RECT; public enum DrawHeightLightType{ RECT, CIRCLE, ROUND_RECT, CUSTOM_ROUND_RECT } /** * 设置要绘制的方向 */ private DrawHintDirection mDirection = DrawHintDirection.RIGHT; public enum DrawHintDirection{ TOP, BOTTOM, LEFT, RIGHT }
自定义View 类文件
import android.content.Context;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.graphics.Shader;import android.text.Layout;import android.text.StaticLayout;import android.text.TextPaint;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;public class UserHintView extends View { private Context mContext; //需要绘制高亮的view private View mHeightLightView; private int[] location; private int viewWidth = 200; private int viewHeight = 200; //绘制高亮类型 private DrawHeightLightType mHeightLightType = DrawHeightLightType.RECT; public enum DrawHeightLightType{ RECT, CIRCLE, ROUND_RECT, CUSTOM_ROUND_RECT } /** * 矩形/圆角矩形 高光扩大范围 */ private int mHeightLightExpandSize = 0; /** * 圆角 */ private int mLeftTopRound = 0; private int mRightTopRound = 0; private int mLeftBottomRound = 0; private int mRightBottomRound = 0; /** * 引导箭头图片 */ private Bitmap mArrow; /** * 设置要绘制的方向 */ private DrawHintDirection mDirection = DrawHintDirection.RIGHT; public enum DrawHintDirection{ TOP, BOTTOM, LEFT, RIGHT } /** * 箭头图片绘制宽高 */ private int mArrowWidth; private int mArrowHeight; /** * 箭头图片偏移量 */ private int mArrowOffsetX = 0; private int mArrowOffsetY = 0; //绘制文字内容 private String mHintText; /** * 文字内容偏移量 */ private int mHintTextOffsetX = 0; private int mHintTextOffsetY = 0; private TextPaint mPaintText = new TextPaint(); private int mTextColor = Color.parseColor("#FFFFFF"); private int mTextSize = 30; //绘制背景颜色 private int mBackgroundColor = Color.parseColor("#50000000"); //画笔 private Paint mPaint = new Paint(); private PorterDuffXfermode mPdf = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT); private PorterDuffXfermode mPdfDstOver = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER); private Paint mPaintBitmap = new Paint(Paint.ANTI_ALIAS_FLAG); //图片着色器 private BitmapShader shader; private Matrix matrix = new Matrix(); public UserHintView(Context context) { super(context); mContext = context; } public UserHintView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; } public UserHintView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; } public UserHintView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mContext = context; } /** * 设置绘制高亮的view * @param view * @return */ public UserHintView setHeightLightView(View view){ mHeightLightView = view; location = new int[]{0 , 0}; if (mHeightLightView != null){ mHeightLightView.getLocationOnScreen(location); viewWidth = mHeightLightView.getMeasuredWidth(); viewHeight = mHeightLightView.getMeasuredHeight(); } location[1] = location[1] - getStatusBarHeight(); return this; } /** * 设置绘制高亮的类型 * @param type 矩形 圆形 圆角矩形 自定义圆角矩形 * @return */ public UserHintView setHeightLightType(DrawHeightLightType type){ mHeightLightType = type; return this; } /** * 设置矩形/圆角矩形 高光扩大范围 * @param size * @return */ public UserHintView setHeightLightExpendSize(int size){ mHeightLightExpandSize = dp2px(size); return this; } /** * 设置引导箭头图片 * @param bitmap * @return */ public UserHintView setArrowBitmap(Bitmap bitmap){ mArrow = bitmap; shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); return this; } /** * 设置引导箭头图片大小 * @param width * @param height * @return */ public UserHintView setArrowSize(int width, int height){ mArrowWidth = dp2px(width); mArrowHeight = dp2px(height); return this; } /** * 设置引导箭头图片 X Y轴 位置偏移量 * @param x * @param y * @return */ public UserHintView setArrowOffsetXY(int x, int y){ mArrowOffsetX = dp2px(x); mArrowOffsetY = dp2px(y); return this; } /** * 设置绘制提示箭头与文字的位置 * @param direction * @return */ public UserHintView setDrawHintDirection(DrawHintDirection direction){ mDirection = direction; return this; } /** * 设置绘制的提示文字 * @param hintText * @return */ public UserHintView setHintText(String hintText){ mHintText = hintText; return this; } /** * 设置绘制提示文字的偏移量 * @param x * @param y * @return */ public UserHintView setHintTextOffsetXY(int x, int y){ mHintTextOffsetX = dp2px(x); mHintTextOffsetY = dp2px(y); return this; } /** * 绘制提示文字的字号 * @param textSize * @return */ public UserHintView setHintTextSize(int textSize){ mTextSize = dp2px(textSize); return this; } /** * 绘制提示文字的颜色 * @param color * @return */ public UserHintView setHintTextColor(int color){ mTextColor = color; return this; } /** * 设置圆角 * @param rectRound * @return */ public UserHintView setRectRound(int rectRound){ return setRectRoundCustom(rectRound, rectRound, rectRound, rectRound); } /** * 设置自定义圆角 * @param leftTop * @param rightTop * @param leftBottom * @param rightBottom * @return */ public UserHintView setRectRoundCustom(int leftTop, int rightTop, int leftBottom, int rightBottom){ mLeftTopRound = dp2px(leftTop); mRightTopRound = dp2px(rightTop); mLeftBottomRound = dp2px(leftBottom); mRightBottomRound = dp2px(rightBottom); return this; } public UserHintView setHintBackgroundColor(int color){ mBackgroundColor = color; return this; } /** * 开始绘制 */ public void create(){ invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setStyle(Paint.Style.FILL); canvas.drawColor(mBackgroundColor); mPaint.setXfermode(mPdf); initHeightLightDraw(canvas); initArrowBitmapDraw(canvas); initHintTextDraw(canvas); } /** * 绘制高光提示 * @param canvas */ private void initHeightLightDraw(Canvas canvas){ mPaint.setStyle(Paint.Style.FILL); //抗锯齿 mPaint.setAntiAlias(true); RectF rectF = new RectF(); rectF.left = location[0] - mHeightLightExpandSize; rectF.top = location[1] - mHeightLightExpandSize; rectF.right = location[0] + viewWidth + mHeightLightExpandSize; rectF.bottom = location[1] + viewHeight + mHeightLightExpandSize; switch (mHeightLightType){ case RECT: canvas.drawRect(rectF, mPaint); break; case CIRCLE: canvas.drawCircle(location[0] + viewWidth / 2f, location[1] + viewHeight / 2f, viewWidth > viewHeight ? viewWidth / 2f + mHeightLightExpandSize : viewHeight / 2f + mHeightLightExpandSize, mPaint); break; case ROUND_RECT: { canvas.drawRoundRect(rectF, mLeftTopRound, mRightBottomRound, mPaint); break; } case CUSTOM_ROUND_RECT: initCustomRoundRect(canvas, location[0], location[1], viewWidth, viewHeight); break; } } /** * 绘制中部十字形,再绘制四个角 * @param canvas * @param x * @param y * @param viewWidth * @param viewHeight */ private void initCustomRoundRect(Canvas canvas, int x, int y, int viewWidth, int viewHeight){ if (mLeftTopRound != 0){ canvas.drawCircle(x + mLeftTopRound, y + mLeftTopRound, mLeftTopRound, mPaint); }else { canvas.drawRect(x, y, x + mRightTopRound, y + mRightTopRound, mPaint); } if (mRightTopRound != 0){ canvas.drawCircle(x + viewWidth - mRightTopRound, y + mRightTopRound, mRightTopRound, mPaint); }else { canvas.drawRect(x + viewWidth - mLeftTopRound, y, x + viewWidth, y + mLeftTopRound, mPaint); } if (mLeftBottomRound != 0){ canvas.drawCircle(x + mLeftBottomRound, y + viewHeight - mLeftBottomRound, mLeftBottomRound, mPaint); }else { canvas.drawRect(x, y + viewHeight - mRightBottomRound , x + mRightBottomRound, y + viewHeight, mPaint); } if (mRightBottomRound != 0){ canvas.drawCircle(x + viewWidth - mRightBottomRound, y + viewHeight - mRightBottomRound, mRightBottomRound, mPaint); }else { canvas.drawRect(x + viewWidth - mLeftBottomRound, y + viewHeight - mLeftBottomRound, x + viewWidth, y + viewHeight, mPaint); } int horLeftRound = Math.max(mLeftTopRound, mLeftBottomRound); int horRightRound = Math.max(mRightTopRound, mRightBottomRound); //中部矩形 - 纵向 canvas.drawRect(x + horLeftRound, y, x +viewWidth - horRightRound, y + viewHeight, mPaint); //中部矩形 - 横向 int verLeftRound = Math.max(mLeftTopRound, mRightTopRound); int verRightRound = Math.max(mLeftBottomRound, mRightBottomRound); canvas.drawRect(x, y + verLeftRound, x + viewWidth, y + viewHeight - verRightRound, mPaint); } /** * 绘制箭头图片 * @param canvas */ private void initArrowBitmapDraw(Canvas canvas){ //抗锯齿 mPaintBitmap.setAntiAlias(true); if (mArrow != null){ if (mArrowWidth == 0 && mArrowHeight == 0){ mArrowWidth = dp2px(150); mArrowHeight = dp2px(150); } // 计算缩放比例 float scaleWidth = ((float) mArrowWidth) / mArrow.getWidth(); float scaleHeight = ((float) mArrowHeight) / mArrow.getHeight(); // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); // 得到新的图片 mArrow = Bitmap.createBitmap(mArrow, 0, 0, mArrow.getWidth(), mArrow.getHeight(), matrix, true); int left = 0, top = 0; //Rect rect = new Rect(); switch (mDirection){ case LEFT: { left = location[0] - mArrowWidth; top = location[1]; /*rect.left = location[0] - mArrowWidth; rect.top = location[1]; rect.right = location[0]; rect.bottom = location[1] + mArrowHeight;*/ break; } case RIGHT: { left = location[0] + viewWidth; top = location[1]; break; } case TOP: { left = location[0]; top = location[1] - mArrowHeight; break; } case BOTTOM: { left = location[0]; top = location[1] + viewHeight; break; } } canvas.drawBitmap(mArrow, left + mArrowOffsetX, top + mArrowOffsetY, mPaintBitmap); } } /** * 绘制提示文字 * @param canvas */ private void initHintTextDraw(Canvas canvas){ int x = 0, y = 0; switch (mDirection) { case LEFT:{ x = location[0] - mArrowWidth + mArrowOffsetX + mHintTextOffsetX; y = location[1] + mArrowHeight + mArrowOffsetY + mHintTextOffsetY; break; } case RIGHT: { x = location[0] + viewWidth + mArrowWidth + mArrowOffsetX + mHintTextOffsetX; y = location[1] + mArrowHeight + mArrowOffsetY + mHintTextOffsetY; break; } case TOP: { x = location[0] + mArrowWidth + mArrowOffsetX + mHintTextOffsetX; y = location[1] - mArrowHeight + mArrowOffsetY + mHintTextOffsetY; break; } case BOTTOM: { x = location[0] + mArrowWidth + mArrowOffsetX + mHintTextOffsetX; y = location[1] + viewHeight + mArrowHeight + mArrowOffsetY + mHintTextOffsetY; break; } } mPaintText.setAntiAlias(true); mPaintText.setColor(mTextColor); mPaintText.setStyle(Paint.Style.FILL); mPaintText.setTextSize(mTextSize); canvas.translate(x, y); StaticLayout myStaticLayout = new StaticLayout(mHintText, mPaintText, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); myStaticLayout.draw(canvas); //canvas.drawText(mHintText, , y, mPaintText); canvas.translate(-x, -y); } private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics()); } private int getWindowWidth(){ return mContext.getResources().getDisplayMetrics().widthPixels; } private int getWindowHeight(){ return mContext.getResources().getDisplayMetrics().heightPixels; } public int getStatusBarHeight() { Resources resources = mContext.getResources(); int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android"); int height = resources.getDimensionPixelSize(resourceId); return height; }}
更多相关文章
- Android(安卓)后台发邮件
- mac Android(安卓)studio3.2版本安装+环境搭建
- LinearLayout 内部 挂件 居中
- EditText属性
- Android入门——基础控件
- Android的OpenGL学习笔记(4)
- Android(安卓)基础UI编程1
- Android中的DownloadManager
- android页面全屏及状态栏和导航栏的(沉浸式)