亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android仿騰訊視頻實(shí)現(xiàn)懸浮窗效果

 更新時(shí)間:2021年06月03日 14:15:26   作者:吐?tīng)柡榻瑿oding  
對(duì)view比較熟悉的同學(xué)們應(yīng)該發(fā)現(xiàn)了,其實(shí)我們的懸浮窗就是一個(gè)view,我們只需要把view添加到windowManager上就可以了。那么,下面通過(guò)本文給大家分享Android仿騰訊視頻實(shí)現(xiàn)懸浮窗效果,一起看看吧

前言

相信大家對(duì)Android懸浮窗應(yīng)該是很熟悉了,比如說(shuō)騰訊視頻、愛(ài)奇藝等APP都有懸浮窗功能。在你打游戲的同時(shí)還可以看視頻,充分利用屏幕空間。還有微信,360手機(jī)衛(wèi)士等APP也有懸浮窗功能。那么Android懸浮窗是怎么實(shí)現(xiàn)的呢?

項(xiàng)目源碼:Android仿騰訊視頻懸浮窗的實(shí)現(xiàn)

其實(shí)并不難,核心代碼就只有一行:

windowManager.addView(view, layoutParams)

效果圖

 對(duì)view比較熟悉的同學(xué)們應(yīng)該發(fā)現(xiàn)了,其實(shí)我們的懸浮窗就是一個(gè)view,我把只需要把view添加到windowManager上就可以了。那么,開(kāi)始講細(xì)節(jié)了:

權(quán)限一定要記得加:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

因?yàn)槲覀兊膽腋〈耙贚auncher上或者在其他APP上面運(yùn)行,所以這里就用到了service,因?yàn)閟ervice可以默默地在后臺(tái)運(yùn)行。

實(shí)現(xiàn)大致步驟:

1.檢查權(quán)限(如果沒(méi)有權(quán)限跳轉(zhuǎn)到授權(quán)界面)

2.在service中用inflate方法獲取我們需要的view,設(shè)置位置參數(shù)等,加入到windowManager里面

3.啟動(dòng)懸浮窗服務(wù)

view布局

<?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>

對(duì)應(yīng)的界面: 

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服務(wù)
        windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
 
        // 新建懸浮窗控件
        val view = LayoutInflater.from(this).inflate(R.layout.window, null)
 
        // 設(shè)置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
        }
 
        //設(shè)置位置
        layoutParams.gravity = Gravity.LEFT or Gravity.TOP
 
        layoutParams.x = windowManager.defaultDisplay.width
        layoutParams.y = 200
 
        //設(shè)置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
        //設(shè)置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
        }
    }
}

先獲取windowManager,加載我們的懸浮窗view,這里的TYPE_APPLICATION_OVERLAY的作用是把我們的view設(shè)置成系統(tǒng)頂層窗口,顯示在其他一切內(nèi)容之上。TYPE_SYSTEM_OVERLAY的作用也是一樣的,只不過(guò)現(xiàn)在被遺棄調(diào)了。

設(shè)置初始位置:

初始位置,這里可以看一下Android坐標(biāo)系相關(guān)知識(shí),Android 零坐標(biāo)在屏幕左上方。這里設(shè)置一下xy坐標(biāo)的位置就可以。

設(shè)置flag: 

設(shè)置flag的作用是讓view不獲取焦點(diǎn)。如果不做處理,view會(huì)遮住屏幕其他控件的點(diǎn)擊事件。

拖拽功能:

FloatingOnTouchListener是一個(gè)內(nèi)部類(lèi),它可以使用FloatingWindowService類(lèi)中的變量。實(shí)現(xiàn)OnTouchListener接口,當(dāng)屏幕點(diǎn)擊時(shí)記錄下當(dāng)前位置,屏幕滑動(dòng)時(shí)計(jì)算出劃過(guò)的距離,修改layoutParams的xy坐標(biāo),調(diào)用windowManager.updateViewLayout(v, layoutParams)方法就可以更新view當(dāng)前位置。



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, "授權(quán)失敗", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "授權(quán)成功", Toast.LENGTH_SHORT).show()
                    startService(Intent(this@MainActivity, FloatingWindowService::class.java))
                }
            }
        }
    }
}

到這里懸浮窗的實(shí)現(xiàn)基本就結(jié)束了。

碼云項(xiàng)目源碼:Android仿騰訊視頻懸浮窗的實(shí)現(xiàn)

以上就是Android仿騰訊視頻實(shí)現(xiàn)懸浮窗效果的詳細(xì)內(nèi)容,更多關(guān)于android懸浮窗的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android實(shí)現(xiàn)短信加密功能(發(fā)送加密短信、解密本地短信)

    Android實(shí)現(xiàn)短信加密功能(發(fā)送加密短信、解密本地短信)

    這篇文章主要介紹了android實(shí)現(xiàn)短信加密功能的相關(guān)資料,功能包括發(fā)送加密短信、解密本地短信,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Android邊框裁切的正確姿勢(shì)實(shí)現(xiàn)示例

    Android邊框裁切的正確姿勢(shì)實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了Android邊框裁切的正確姿勢(shì)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Android接入支付寶和微信支付的方法

    Android接入支付寶和微信支付的方法

    這篇文章主要介紹了Android接入支付寶和微信支付的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Android自制精彩彈幕效果

    Android自制精彩彈幕效果

    這篇文章主要為大家詳細(xì)介紹了Android自制精彩彈幕效果,彈幕垂直方向可固定隨機(jī),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 分析Android中應(yīng)用的啟動(dòng)流程

    分析Android中應(yīng)用的啟動(dòng)流程

    不知道大家有沒(méi)有好奇過(guò)點(diǎn)擊Launcher圖標(biāo)時(shí),到喚起一個(gè)應(yīng)用頁(yè)面,這個(gè)流程會(huì)是怎么樣的?那這篇文章的目的就是盡可能梳理清楚流程,能夠讓大家對(duì)整個(gè)流程有一個(gè)相對(duì)清晰的認(rèn)知。下面跟著小編一起學(xué)習(xí)學(xué)習(xí)。
    2016-08-08
  • Android帶氣泡的第三方Tab選項(xiàng)卡

    Android帶氣泡的第三方Tab選項(xiàng)卡

    這篇文章主要介紹了Android帶氣泡的第三方Tab選項(xiàng)卡的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • Android實(shí)現(xiàn)簡(jiǎn)單底部導(dǎo)航欄 Android仿微信滑動(dòng)切換效果

    Android實(shí)現(xiàn)簡(jiǎn)單底部導(dǎo)航欄 Android仿微信滑動(dòng)切換效果

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)單底部導(dǎo)航欄,Android仿微信滑動(dòng)切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android開(kāi)發(fā)實(shí)現(xiàn)Gallery畫(huà)廊效果的方法

    Android開(kāi)發(fā)實(shí)現(xiàn)Gallery畫(huà)廊效果的方法

    這篇文章主要介紹了Android開(kāi)發(fā)實(shí)現(xiàn)Gallery畫(huà)廊效果的方法,結(jié)合具體實(shí)例形式分析了Android使用Gallery實(shí)現(xiàn)畫(huà)廊功能的具體操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-06-06
  • Android應(yīng)用中使用及實(shí)現(xiàn)系統(tǒng)“分享”接口實(shí)例

    Android應(yīng)用中使用及實(shí)現(xiàn)系統(tǒng)“分享”接口實(shí)例

    為了應(yīng)用的推廣、傳播,很多的應(yīng)用中都有“分享”功能,這篇文章主要介紹了Android應(yīng)用中使用及實(shí)現(xiàn)系統(tǒng)“分享”接口實(shí)例,有興趣的可以了解一下。
    2016-12-12
  • Android開(kāi)發(fā)中使用achartengine繪制各種圖表的方法

    Android開(kāi)發(fā)中使用achartengine繪制各種圖表的方法

    這篇文章主要介紹了Android開(kāi)發(fā)中使用achartengine繪制各種圖表的方法,結(jié)合具體實(shí)例形式分析了Android基于圖表生成類(lèi)庫(kù)achartengine進(jìn)行圖表繪制的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10

最新評(píng)論