안 드 로 이 드 가 텐 센트 영상 을 모방 하여 부상 창 효 과 를 실현 하 다.

9368 단어 android부유 창
머리말
여러분 들 은 안 드 로 이 드 부상 창 에 대해 잘 알 고 있 을 것 이 라 고 믿 습 니 다.예 를 들 어 텐 센트 영상,아이 치 이 등 앱 은 모두 부상 창 기능 을 가지 고 있 습 니 다.게임 을 하면 서 영상 도 볼 수 있 고 스크린 공간 을 충분히 활용 할 수 있다.위 챗,360 모 바 일 가 디 언 스 등 앱 에 도 부유 창 기능 이 있다.그렇다면 안 드 로 이 드 부상 창 은 어떻게 이 루어 졌 을 까?
프로젝트 원본:안 드 로 이 드 모방 텐 센트 영상 부상 창의 실현
사실 어렵 지 않 습 니 다.핵심 코드 는 한 줄 밖 에 없습니다.

windowManager.addView(view, layoutParams)
효과 도

 view 에 익숙 한 친구 들 이 발 견 했 을 것 입 니 다.사실 우리 의 부상 창 은 view 입 니 다.저 는 view 를 window Manager 에 추가 하면 됩 니 다.그럼 세부 사항 을 말씀 드 리 겠 습 니 다.
권한 추가:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
우리 의 부상 창 은 Launcher 나 다른 앱 에서 실행 되 어야 하기 때문에 여 기 는 service 를 사용 합 니 다.service 는 묵묵히 배경 에서 실행 할 수 있 기 때 문 입 니 다.
대체적인 절 차 를 실현 하 다.
1.권한 검사(권한 이 없 으 면 권한 부여 인터페이스 로 이동)
2.service 에서 inflate 방법 으로 우리 가 필요 로 하 는 view 를 얻 고 위치 매개 변 수 를 설정 하 는 등 window Manager 에 가입 합 니 다.
3.부상 창 서비스 시작
레이아웃 보기

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
 
    <ImageView
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:src="@drawable/huge"></ImageView>
 
    <ImageView
        android:id="@+id/close"
        android:src="@drawable/close"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginLeft="170dp">
 
    </ImageView>
 
</FrameLayout>
대응 하 는 인터페이스: 

FloatingWindowService

package com.example.floatingwindow
 
import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.view.*
import android.widget.ImageView
import android.widget.Toast
 
 
class FloatingWindowService : Service(){
 
    private lateinit var layoutParams: WindowManager.LayoutParams
    private lateinit var windowManager: WindowManager
 
    override fun onBind(intent: Intent): IBinder? {
        // TODO: Return the communication channel to the service.
        throw UnsupportedOperationException("Not yet implemented")
    }
 
    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        showFloatingWindow()
        return super.onStartCommand(intent, flags, startId)
    }
 
    @SuppressLint("ClickableViewAccessibility")
    private fun showFloatingWindow() {
        //   WindowManager  
        windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
 
        //        
        val view = LayoutInflater.from(this).inflate(R.layout.window, null)
 
        //   LayoutParam
        layoutParams = WindowManager.LayoutParams()
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        } else {
            layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE
        }
 
        //    
        layoutParams.gravity = Gravity.LEFT or Gravity.TOP
 
        layoutParams.x = windowManager.defaultDisplay.width
        layoutParams.y = 200
 
        //  flag
        layoutParams.flags =
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR or
                    WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
        //  view   
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
 
        //      
        view.setOnTouchListener(FloatingOnTouchListener())
 
        val close = view.findViewById<ImageView>(R.id.close)
 
        close.setOnClickListener {
            stopSelf()
            windowManager.removeView(view)
            Toast.makeText(this,"close",Toast.LENGTH_SHORT).show()
        }
 
        //          WindowManager
        windowManager.addView(view, layoutParams)
    }
 
    override fun onDestroy() {
        super.onDestroy()
        Toast.makeText(this,"onDestroy",Toast.LENGTH_SHORT).show()
    }
 
    inner class FloatingOnTouchListener : View.OnTouchListener {
 
        private var x = 0f
        private var y = 0f
 
        @SuppressLint("ClickableViewAccessibility")
        override fun onTouch(v: View?, event: MotionEvent?): Boolean {
            when(event?.action){
 
                MotionEvent.ACTION_DOWN ->{
                    x = event.rawX
                    y = event.rawY
                }
 
                MotionEvent.ACTION_MOVE ->{
                    val nowX = event.rawX
                    val nowY = event.rawY
                    val movedX = nowX - x
                    val movedY = nowY - y
                    x = nowX
                    y = nowY
                    layoutParams.x = (layoutParams.x + movedX).toInt()
                    layoutParams.y = (layoutParams.y + movedY).toInt()
                    windowManager.updateViewLayout(v, layoutParams)
                }
 
                MotionEvent.ACTION_UP ->{
 
                }
 
            }
            return false
        }
    }
}
먼저 window Manager 를 가 져 와 서 우리 의 부상 창 view 를 불 러 옵 니 다.여기 TYPEAPPLICATION_오 버 레이 는 우리 뷰 를 시스템 최상 위 창 으로 설정 해 다른 모든 콘 텐 츠 위 에 표시 하 는 역할 을 한다.TYPE_SYSTEM_오 버 레이 의 역할 도 마 찬가 지 였 지만,지금 은 버 려 졌 다.
초기 위치 설정:
초기 위치,안 드 로 이 드 좌표계 지식 을 볼 수 있 습 니 다.안 드 로 이 드 0 좌 표 는 화면 왼쪽 위 에 있 습 니 다.여기 xy 좌표 의 위 치 를 설정 하면 됩 니 다.
flag 설정: 
flag 를 설정 하 는 역할 은 view 가 초점 을 얻 지 못 하 게 하 는 것 입 니 다.처리 하지 않 으 면 view 는 화면의 다른 컨트롤 의 클릭 이 벤트 를 가 립 니 다.
드래그 기능:
FloatingOnTouchListener 는 내부 클래스 로 FloatingWindowService 클래스 의 변 수 를 사용 할 수 있 습 니 다.OnTouchListener 인 터 페 이 스 를 실현 합 니 다.화면 이 클릭 할 때 현재 위 치 를 기록 하고 화면 이 미 끄 러 질 때 그 은 거 리 를 계산 합 니 다.layotParams 의 xy 좌 표를 수정 하고 windowManager.updateViewLayout(v,layotParams)방법 으로 view 현재 위 치 를 업데이트 할 수 있 습 니 다.
MainActivity

package com.example.floatingwindow
 
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
 
 
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        startFloatingService()
    }
 
    private fun startFloatingService() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName")), 0)
            } else {
                startService(Intent(this@MainActivity, FloatingWindowService::class.java))
            }
        }
    }
 
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 0) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                    Toast.makeText(this, "    ", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "    ", Toast.LENGTH_SHORT).show()
                    startService(Intent(this@MainActivity, FloatingWindowService::class.java))
                }
            }
        }
    }
}
여기까지 부상 창의 실현 은 기본적으로 끝났다.
코드 클 라 우 드 프로젝트 소스 코드:안 드 로 이 드 모방 텐 센트 영상 부상 창의 실현
이상 은 안 드 로 이 드 가 텐 센트 영상 을 모방 하여 부상 창 효 과 를 실현 하 는 상세 한 내용 입 니 다.안 드 로 이 드 부상 창 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기