Android 简单实现半透明新手指引 蒙版

一.效果图

1.png
2.png

二.简单实现的思路

就是在我们需要提示的页面上方覆盖一个半透明的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>

四.代码中用到的图

蒙版透明图

contact.png

按钮图

kf.png

最后的福利

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容