一.效果图
二.简单实现的思路
就是在我们需要提示的页面上方覆盖一个半透明的activity,首先获取需要提示的位置坐标,然后传给上方覆盖的activity.最后在activity上面相应的位置画出指引内容.然后点击可关闭上方的提示页,从而取消提示.
三.代码实现
首先实现蒙版activity
public class TipsActivity extends Activity {
private static final String TAG = "TipsActivity";
private int[] mLocs;
@BindView(R.id.tips_rootview)
RelativeLayout mRlRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//取消title
setContentView(R.layout.activity_tips);
Intent intent = getIntent();
mLocs = intent.getIntArrayExtra("loc");//获取坐标
ButterKnife.bind(this);
initView();
}
private void initView() {
PrintLog.d(TAG,"initView");
TipsView tipsView = new TipsView(this);//将坐标传给自定义view
tipsView.setCircleLocation(mLocs);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mRlRootView.addView(tipsView, layoutParams);
}
@OnClick(R.id.tips_rootview)
public void clickClose() {
finish();
overridePendingTransition(0, 0); //取消动画效果
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
overridePendingTransition(0, 0);
return true;
}
return super.onKeyDown(keyCode, event);
}
}
R.layout.activity_tips
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:clickable="true"
android:id="@+id/tips_rootview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
Manifest
<activity android:name=".module.guide.masking.TipsActivity" android:theme="@style/ThemeTips" />
ThemeTips
<!-- 重新主题去掉activity切换的动画效果 -->
<style name="ThemeTips" parent="@android:style/Theme.Translucent.NoTitleBar">
<item name="android:windowAnimationStyle">@style/Animation</item>
</style>
<style name="Animation">
<item name="android:activityOpenEnterAnimation">@null</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@null</item>
<item name="android:taskOpenEnterAnimation">@null</item>
<item name="android:taskOpenExitAnimation">@null</item>
<item name="android:taskCloseEnterAnimation">@null</item>
<item name="android:taskCloseExitAnimation">@null</item>
<item name="android:taskToFrontEnterAnimation">@null</item>
<item name="android:taskToFrontExitAnimation">@null</item>
<item name="android:taskToBackEnterAnimation">@null</item>
<item name="android:taskToBackExitAnimation">@null</item>
</style>
TipsView
public class TipsView extends FrameLayout {
private final Context mContext;
private int[] mCircleLocation;
public TipsView(Context context) {
this(context, null);
}
public TipsView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TipsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
initView();
}
private void initView() {
setBackgroundColor(Color.parseColor("#7f000000"));//半透明底色
}
public void setCircleLocation(int[] location) {
this.mCircleLocation = location;
invalidate(); //重新绘画
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCircleLocation != null) {
//掏空一个圆形
Paint paintarc = new Paint(Paint.ANTI_ALIAS_FLAG);
PorterDuffXfermode porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
paintarc.setXfermode(porterDuffXfermode);
paintarc.setAntiAlias(true);
RectF rectF = new RectF(mCircleLocation[0], mCircleLocation[1], mCircleLocation[2], mCircleLocation[3]);
canvas.drawArc(rectF, 0, 360, true, paintarc);
//画虚线
Paint paintdashed = new Paint(Paint.ANTI_ALIAS_FLAG);
paintdashed.setStyle(Paint.Style.STROKE);
paintdashed.setColor(Color.WHITE);
paintdashed.setStrokeWidth(1);
PathEffect pathEffect = new DashPathEffect(new float[]{10, 10}, 0);
paintdashed.setPathEffect(pathEffect);
canvas.drawArc(rectF, 0, 360, true, paintdashed);
//画指引图片
Paint paintImage = new Paint(Paint.ANTI_ALIAS_FLAG);
Bitmap bitmap = BitmapFactory.decodeResource(UIUtils.getResources(), R.drawable.contact);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int def = UIUtils.dip2px(20);
int left = mCircleLocation[0] - width+def;
int top = mCircleLocation[1] - height;
canvas.drawBitmap(bitmap, left, top, paintImage);
}
}
}
蒙版的activity实现后 以下就是调用蒙版activity使其显示在需要提示页面的上层 MaskingActivity是需要提示的页面
public class MaskingActivity extends AppCompatActivity {
private static final String TAG = "MaskingActivity";
@BindView(R.id.mask_bt)
AppCompatButton mBtMasking;
private int mHeight;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_masking);
setTitle("蒙版");
ButterKnife.bind(this);
showMask();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
}
//onCreat中直接去测量view的大小是测不出来的 所以在这个demo中我延时500ms去测量
//实际使用一般在网络加载完成后去测量view的大小然后去显示蒙版
private void showMask() {
mBtMasking.postDelayed(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mHeight = getSupportActionBar().getHeight();
int left = mBtMasking.getLeft();
int right = mBtMasking.getRight();
int top = mBtMasking.getTop()+mHeight;
int bottom = mBtMasking.getBottom()+mHeight;
int loc[] = {left,top,right,bottom};
Intent intent = new Intent(MaskingActivity.this,TipsActivity.class);
intent.putExtra("loc",loc);
startActivity(intent);
}
});
}
},500);
}
R.layout.activity_masking
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/cardview_shadow_end_color"
>
<FrameLayout
android:background="@color/colorPrimary"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="120dp"/>
<android.support.v7.widget.AppCompatButton
android:background="@drawable/kf"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:id="@+id/mask_bt"
android:layout_width="80dp"
android:layout_height="80dp" />
</RelativeLayout>
四.代码中用到的图
蒙版透明图
按钮图