Android 新手引導頁面 遮罩View
將自己想要的新手引導介面利用Mask的形式蓋到View的上方,可以建立自定義檢視的Mask利用OnDraw來執行遮罩。使用背景半透明,遮罩引導層是很常用的一個功能,所以我自己做一個範例來實現。
文章目錄
- 創建遮罩View
- 添加遮罩View
- 畫面布局
- View圖層
- Github
1.創建遮罩View
package com.example.maskdemo
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
/**
* Author: Wade
* E-mail: tony91097@gmail.com
* Date: 2021/9/22
*/
@SuppressLint("ViewConstructor")
class MaskView(context: Context, private val decorView: FrameLayout) : View(context) {
private val path = Path()
private val maskPaint = Paint().apply {
color = Color.parseColor("#90000000")
}
private var nextX = 0f
private var nextY = 0f
private var nextR = 0f
private var previousX = 0f
private var previousY = 0f
private var previousR = 0f
private var confirmX = 0f
private var confirmY = 0f
private var confirmR = 0f
//設置View遮罩位子
fun setNext(view: View, radius: Float) {
this.nextX = view.x + view.width / 2
this.nextY = view.y + view.height / 2
this.nextR = radius
}
//設置View遮罩位子
fun setPrevious(view: View, radius: Float) {
this.previousX = view.x + view.width / 2
this.previousY = view.y + view.height / 2
this.previousR = radius
}
//設置View遮罩位子
fun setButton(view: View, radius: Float) {
this.confirmX = view.x + view.width / 2
this.confirmY = view.y + view.height / 2
this.confirmR = radius
}
//CW順時針畫 CCW逆時針畫 挖洞
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.run {
path.addRect(0f, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW)
path.addCircle(confirmX, confirmY, confirmR, Path.Direction.CCW)
path.addCircle(previousX, previousY, previousR, Path.Direction.CCW)
path.addCircle(nextX, nextY, nextR, Path.Direction.CCW)
drawPath(path, maskPaint)
}
}
//觸碰到指定座標移除遮罩
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent?): Boolean {
event?.apply {
if (MotionEvent.ACTION_DOWN == action) {
if (confirmX - confirmR < event.x && confirmX + confirmR > event.x && confirmY - confirmR < event.y && confirmY + confirmR > event.y) {
decorView.removeView(this@MaskView)
}
}
}
return true
}
}
2.添加遮罩View
package com.example.maskdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.FrameLayout
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatImageView
class MainActivity : AppCompatActivity() {
lateinit var decorView: FrameLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//隱藏actionbar 不然高度會不同
supportActionBar?.hide()
//最底層View
decorView = window.decorView.findViewById(android.R.id.content)
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
//取得View
val next = findViewById<AppCompatImageView>(R.id.next)
val previous = findViewById<AppCompatImageView>(R.id.previous)
val confirm = findViewById<AppCompatButton>(R.id.confirm)
//設置xyr
val maskView = MaskView(this, decorView)
maskView.setButton(confirm, confirm.width / 1.5f)
maskView.setNext(next, next.width / 1.5f)
maskView.setPrevious(previous, previous.width / 1.5f)
decorView.addView(maskView)
}
}
3.畫面布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/next"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginEnd="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/previous"
app:srcCompat="@drawable/next" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/previous"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginStart="50dp"
android:layout_marginTop="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/previous" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="確認"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/next"
app:layout_constraintStart_toStartOf="@+id/previous"
app:layout_constraintTop_toBottomOf="@+id/previous" />
</androidx.constraintlayout.widget.ConstraintLayout>
4.View圖層
5.Github
Android 新手引導頁面 遮罩View