Skip to content

Commit

Permalink
新增showcase新手引导控件
Browse files Browse the repository at this point in the history
  • Loading branch information
r17171709 committed Jul 4, 2017
1 parent e6edd97 commit 85761a1
Show file tree
Hide file tree
Showing 8 changed files with 434 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.renyu.commonlibrary.views.showcaselibrary;

/**
* Created by Administrator on 2017/7/3.
*/

public class CalculatorBean {
FocusShape mFocusShape;
int mCircleCenterX;
int mCircleCenterY;
int mCircleRadius;
// 圆角矩形专用
int mFocusWidth;
int mFocusHeight;

public FocusShape getmFocusShape() {
return mFocusShape;
}

public void setmFocusShape(FocusShape mFocusShape) {
this.mFocusShape = mFocusShape;
}

public int getmCircleCenterX() {
return mCircleCenterX;
}

public void setmCircleCenterX(int mCircleCenterX) {
this.mCircleCenterX = mCircleCenterX;
}

public int getmCircleCenterY() {
return mCircleCenterY;
}

public void setmCircleCenterY(int mCircleCenterY) {
this.mCircleCenterY = mCircleCenterY;
}

public int getmFocusWidth() {
return mFocusWidth;
}

public void setmFocusWidth(int mFocusWidth) {
this.mFocusWidth = mFocusWidth;
}

public int getmFocusHeight() {
return mFocusHeight;
}

public void setmFocusHeight(int mFocusHeight) {
this.mFocusHeight = mFocusHeight;
}

public int getmCircleRadius() {
return mCircleRadius;
}

public void setmCircleRadius(int mCircleRadius) {
this.mCircleRadius = mCircleRadius;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.renyu.commonlibrary.views.showcaselibrary;

/**
* Created by Administrator on 2017/7/3.
*/

public enum FocusShape {
CIRCLE,
ROUNDED_RECTANGLE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package com.renyu.commonlibrary.views.showcaselibrary;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;

import java.util.ArrayList;

/**
* Created by Administrator on 2017/7/3.
*/

public class ShowCaseImageView extends ImageView {

int mBackgroundColor= Color.TRANSPARENT;
int mFocusBorderColor=Color.BLACK;
int mFocusBorderSize=6;
// 椭圆圆角范围
RectF rectF;
// 默认背景
Bitmap mBitmap;
// 高亮部分集合
ArrayList<CalculatorBean> mCalculatorBeen;

Paint mBackgroundPaint;
// 设置高亮点清除中心Paint
Paint mErasePaint;
// 设置高亮点Paint
Paint mCircleBorderPaint;
Path mPath;

// 设置是否可以播放动画
boolean mAnimationEnabled=false;
// 当前步进值
int mAnimCounter=0;
// 当前步进趋势
int mStep=1;
// 最大步进值
final int ANIM_COUNTER_MAX=20;
// 最大变化范围
float animMoveFactor=0.5f;

public ShowCaseImageView(Context context) {
this(context, null);
}

public ShowCaseImageView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}

public ShowCaseImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

init();
}

private void init() {
// 3.0之后开启硬件加速
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setLayerType(LAYER_TYPE_HARDWARE, null);
}
// 由于性能限制,onDraw()方法不被执行的解决方法
setWillNotDraw(false);

setBackgroundColor(Color.TRANSPARENT);

mBackgroundPaint=new Paint();
mBackgroundPaint.setAntiAlias(true);
mBackgroundPaint.setColor(mBackgroundColor);
mBackgroundPaint.setAlpha(0xFF);

mErasePaint=new Paint();
mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mErasePaint.setAlpha(0xFF);

mCircleBorderPaint=new Paint();
mCircleBorderPaint.setColor(mFocusBorderColor);
mCircleBorderPaint.setStrokeWidth(mFocusBorderSize);
mCircleBorderPaint.setStyle(Paint.Style.STROKE);
mCircleBorderPaint.setStrokeJoin(Paint.Join.ROUND);
mCircleBorderPaint.setStrokeCap(Paint.Cap.ROUND);
mCircleBorderPaint.setPathEffect(new DashPathEffect(new float[] {10, 20}, 0));

rectF=new RectF();

mPath=new Path();
}

public void setmCalculatorBeen(ArrayList<CalculatorBean> mCalculatorBeen) {
this.mCalculatorBeen = mCalculatorBeen;
}

public void setmAnimationEnabled(boolean mAnimationEnabled) {
this.mAnimationEnabled = mAnimationEnabled;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if (mBitmap == null) {
mBitmap= Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
// 把图片设置成透明
mBitmap.eraseColor(0xb2000000);
}
canvas.drawBitmap(mBitmap, 0, 0, mBackgroundPaint);
if (mCalculatorBeen!=null) {
for (CalculatorBean calculatorBean : mCalculatorBeen) {
if (calculatorBean.getmFocusShape()==FocusShape.CIRCLE) {
drawCircle(canvas, calculatorBean);
}
else if (calculatorBean.getmFocusShape()==FocusShape.ROUNDED_RECTANGLE) {
drawRoundedRectangle(canvas, calculatorBean);
}
}
if (mAnimationEnabled) {
if (mAnimCounter==ANIM_COUNTER_MAX) {
mStep=-1;
}
else if (mAnimCounter==0) {
mStep=1;
}
mAnimCounter+=mStep;
}
}
postInvalidate();
}

/**
* 绘制圆形
* @param canvas
* @param calculatorBean
*/
private void drawCircle(Canvas canvas, CalculatorBean calculatorBean) {
// 绘制高亮
canvas.drawCircle(calculatorBean.getmCircleCenterX(), calculatorBean.getmCircleCenterY(), calculatorBean.getmCircleRadius()+ mAnimCounter*animMoveFactor, mErasePaint);
// 绘制其余部分
mPath.reset();
mPath.moveTo(calculatorBean.getmCircleCenterX(), calculatorBean.getmCircleCenterY());
mPath.addCircle(calculatorBean.getmCircleCenterX(), calculatorBean.getmCircleCenterY(), calculatorBean.getmCircleRadius()+ mAnimCounter*animMoveFactor, Path.Direction.CW);
canvas.drawPath(mPath, mCircleBorderPaint);
}

/**
* 绘制圆角矩形
* @param canvas
* @param calculatorBean
*/
private void drawRoundedRectangle(Canvas canvas, CalculatorBean calculatorBean) {
// 绘制高亮
int centerX=calculatorBean.getmCircleCenterX();
int centerY=calculatorBean.getmCircleCenterY();
float left=centerX-calculatorBean.getmFocusWidth()/2- mAnimCounter*animMoveFactor;
float top=centerY-calculatorBean.getmFocusHeight()/2- mAnimCounter*animMoveFactor;
float right=centerX+calculatorBean.getmFocusWidth()/2+ mAnimCounter*animMoveFactor;
float bottom=centerY+calculatorBean.getmFocusHeight()/2+ mAnimCounter*animMoveFactor;
canvas.drawRoundRect(new RectF(left, top, right, bottom), calculatorBean.getmCircleRadius(), calculatorBean.getmCircleRadius(), mErasePaint);
// 绘制其余部分
mPath.reset();
mPath.moveTo(calculatorBean.getmCircleCenterX(), calculatorBean.getmCircleCenterY());
mPath.addRoundRect(new RectF(left, top, right, bottom), calculatorBean.getmCircleRadius(), calculatorBean.getmCircleRadius(), Path.Direction.CW);
canvas.drawPath(mPath, mCircleBorderPaint);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.renyu.commonlibrary.views.showcaselibrary;

import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

/**
* Created by Administrator on 2017/7/3.
*/

public class ShowCaseView {

Queue<View> mQueue;
View currentView;

Activity context;

public ShowCaseView(Activity context) {
this.context = context;
}

public void addViews(ArrayList<View> views) {
mQueue=new LinkedList<>();
mQueue.addAll(views);
}

public void show() {
if (!mQueue.isEmpty()) {
currentView=mQueue.poll();
((ViewGroup) context.getWindow().getDecorView()).addView(currentView);
}
}

public void dismiss() {
if (currentView!=null) {
((ViewGroup) context.getWindow().getDecorView()).removeView(currentView);
}
show();
}

public void cancel() {
if (!mQueue.isEmpty()) {
mQueue.clear();
}
if (currentView!=null) {
((ViewGroup) context.getWindow().getDecorView()).removeView(currentView);
}
}
}
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.LoginActivity">
<activity android:name=".activity.ShowcaseActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
Loading

0 comments on commit 85761a1

Please sign in to comment.