The purpose of this paper is to realize a Notification popup similar to Notification. The effect is to pop up automatically when there is information, which can be cancelled by sliding up or automatically cancelled within a specified time. No Notification will be generated in the Notification bar. Please point out any shortcomings or better implementation methods. Let’s start with the renderings.

1. Find DecorView

As you can see in the figure above, a DecorView is the top-level View, the root node of the View, and inherits from FrameLayout. And that step is to find the DecorView

fun findDecorView(activity: Activity): ViewGroup? {
    var view: View? = activity.findViewById(android.R.id.content)
    var frameLayout: FrameLayout? = null
    while(view ! =null) {
        val parent = view.parent
        view = if (parent is View) parent else null
        if (parent is FrameLayout) {
            frameLayout = parent
        }
    }
    return frameLayout
}

// I find it possible to fetch the DecorView directly from the current activity
fun findDecorView2(activity: Activity): ViewGroup = activity.window.decorView as ViewGroup
Copy the code

2. Add popovers to the DecorView

fun show(a) {
    val notificationView = currentActivity.layoutInflater.inflate(R.layout.layout_notification, null)
    val layoutNotification: RelativeLayout = notificationView.findViewById(R.id.layout_notification)
    
    valdecorView = findDecorView(currentActivity) ? :return
    decorView.postDelayed(kotlinx.coroutines.Runnable { decorView.addView(notificationView) }, 100)
    
    // Add a pop-up animation
    notificationView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.notification_enter))

    // Set automatic shutdown within 3 seconds
    notificationView.postDelayed({ 
        val parent = notificationView.parent
        if (parent is ViewGroup) {
            parent.removeView(notificationView)
        }
    }, 3000)
    
    // Set the listener
    setOnTouchListener(notificationView)
}
Copy the code

3. Listen to user operations

fun setOnTouchListener(view: View) {
    var x = 0f
    var y = 0f
    // Slide the minimum distance
    val touchSlop = ViewConfiguration.get(activity).scaledTouchSlop 
    view.setOnTouchListener { view, event ->
        when(event? .action) { MotionEvent.ACTION_DOWN -> { x = event.x y = event.y } MotionEvent.ACTION_UP -> {// Calculate the horizontal and vertical movement distance
                val offsetX = event.x - x
                val offsetY = event.y - y
       
                // If the sliding distance is less than the minimum sliding distance, it is considered a click event
                if (abs(offsetX) < touchSlop && abs(offsetY) < touchSlop) {
                    // Click the event
                    context.startActivity(Intent(context, ResultActivity::class.java))
                }
                // Check whether there is a slide up operation
                else if (offsetY < -touchSlop) {
                    removeView(view)
                } 
            }
        }
        true}}fun removeView(view: View) {
    // Add slide up unanimate effect
    view.startAnimation(AnimationUtils.loadAnimation(this, R.anim.notification_exit))
    
    notificationView.postDelayed({ 
        val parent = notificationView.parent
        if (parent is ViewGroup) {
            parent.removeView(notificationView)
        }
    }, 100)}Copy the code