美文网首页Run_实用资料搜集Android知识
Android 简单实现半透明新手指引 蒙版

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

作者: callxkj | 来源:发表于2016-11-03 11:19 被阅读6063次

一.效果图

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

相关文章

网友评论

本文标题:Android 简单实现半透明新手指引 蒙版

本文链接:https://www.haomeiwen.com/subject/vevbuttx.html