안 드 로 이 드 가 텐 센트 영상 을 모방 하여 부상 창 효 과 를 실현 하 다.
여러분 들 은 안 드 로 이 드 부상 창 에 대해 잘 알 고 있 을 것 이 라 고 믿 습 니 다.예 를 들 어 텐 센트 영상,아이 치 이 등 앱 은 모두 부상 창 기능 을 가지 고 있 습 니 다.게임 을 하면 서 영상 도 볼 수 있 고 스크린 공간 을 충분히 활용 할 수 있다.위 챗,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))
}
}
}
}
}
여기까지 부상 창의 실현 은 기본적으로 끝났다.코드 클 라 우 드 프로젝트 소스 코드:안 드 로 이 드 모방 텐 센트 영상 부상 창의 실현
이상 은 안 드 로 이 드 가 텐 센트 영상 을 모방 하여 부상 창 효 과 를 실현 하 는 상세 한 내용 입 니 다.안 드 로 이 드 부상 창 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.