In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Editor to share with you how to achieve Android floating window, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to understand it!
1. Preface
At present, many applications have the function of a small suspended window. For example, when watching a live broadcast, the small window of the live broadcast can still be displayed on the screen when you return to the desktop with the Home key.
two。 Principle
Window we should be familiar with, it is an interface class, the specific implementation class is PhoneWindow, which can manage View. WindowManager is an interface class that inherits from ViewManager. It is known from the name that it is used to manage Window, and its implementation class is WindowManagerImpl. If we want to add, update, and delete Window (View), we can use WindowManager,WindowManager to leave the specific work to WindowManagerService. All we need to know here is that WindowManager can be used to manage Window.
WindowManager is an interface class that inherits from ViewManager,ViewManager and defines three methods that are distributed to add, update, and delete View, as follows:
Public interface ViewManager {public void addView (View view, ViewGroup.LayoutParams params); public void updateViewLayout (View view, ViewGroup.LayoutParams params); public void removeView (View view);}
WindowManager also inherits these methods, and the parameters passed in by these methods are of type View, indicating that Window exists in the form of View.
3. Concrete realization
3.1 floating window layout
For the simple layout of the suspension window, please refer to the layout_floating_window.xml file below. The top dark part of the FrameLayout layout is used to achieve the dragging function of the suspension window, click on the upper right corner ImageView to close the suspension window, the remaining area to display content, here is simply to display the text content, do not do complex things, so only set TextView.
3.2 realization of suspension window
1. Use Service Service
Service is an application component that can perform long-running operations in the background without providing an interface, can be started by other application components, and will continue to run in the background even if the user switches to another application. To ensure that when applied in the background, the suspension window can still be displayed normally, so you can use Service here.
two。 Get WindowManager and set LayoutParamsprivate lateinit var windowManager: WindowManagerprivate lateinit var layoutParams: WindowManager.LayoutParamsoverride fun onCreate () {/ / get WindowManager windowManager = getSystemService (WINDOW_SERVICE) as WindowManager layoutParams = WindowManager.LayoutParams () .apply {/ / implement to display floating window type = if (Build.VERSION.SDK_INT > = Build.VERSION_CODES.O) {WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY above other applications and windows } else {WindowManager.LayoutParams.TYPE_PHONE} format = PixelFormat.RGBA_8888 / / set the size and position of the floating window gravity = Gravity.START or Gravity.TOP flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE width = 600000 height = 600x = 300y = 300}} 3. Create a View and add it to WindowManagerprivate lateinit var floatingView: Viewoverride fun onStartCommand (intent: Intent?, flags: Int, startId: Int): Int {if (Settings.canDrawOverlays (this)) {floatingView = LayoutInflater.from (this). Evaluate (R.layout.layout_floating_window.xml, null) windowManager.addView (floatingView, layoutParams)} return super.onStartCommand (intent, flags, startId)} 4. Realize the function of dragging and closing the floating window / / the coordinates of the floating window private var x = 0private var y = 0override fun onStartCommand (intent: Intent?, flags: Int, startId: Int): Int {if (Settings.canDrawOverlays (this)) {floatingView = LayoutInflater.from (this). Evaluate (R.layout.layout_floating_window.xml, null) windowManager.addView (floatingView) LayoutParams) / / Click the close button in the upper right corner of the floating window to close the floating window floatingView.findViewById (R.id.iv_close). SetOnClickListener {windowManager.removeView (floatingView)} / / to achieve the floating window drag function, by changing the layoutParams to achieve floatingView.findViewById (R.id.layout_drag) .setOnTouchListener {v Event-> when (event.action) {MotionEvent.ACTION_DOWN-> {x = event.rawX.toInt () y = event.rawY.toInt ()} MotionEvent.ACTION_MOVE-> {val currentX = event.rawX.toInt () val currentY = event.rawY.toInt () Val offsetX = currentX-x val offsetY = currentY-y x = currentX y = currentY layoutParams.x = layoutParams.x + offsetX layoutParams.y = layoutParams.y + offsetY / / Update floatingView windowManager.updateViewLayout (floatingView LayoutParams)}} true} return super.onStartCommand (intent, flags, startId)} 5. Private var receiver: MyReceiver? = nulloverride fun onCreate () {/ / registered broadcast receiver = MyReceiver () val filter = IntentFilter () filter.addAction ("android.intent.action.MyReceiver") registerReceiver (receiver, filter)} inner class MyReceiver: BroadcastReceiver () {override fun onReceive (context: Context) Intent: Intent) {val content = intent.getStringExtra ("content"): "" / / Update UI val message = Message.obtain () message.what = 0 message.obj = content handler.sendMessage (message)}} val handler = Handler (this.mainLooper) {msg-> tvContent.text = msg.obj as String false} via Handler
Messages can be sent to Service by broadcast in Activity
Fun sendMessage (view: View?) {Intent ("android.intent.action.MyReceiver"). Apply {putExtra ("content", "Hello, World!") SendBroadcast (this)} 6. Set permissions
Permission is required for the display of suspended windows. Add:
In addition, you need to set permissions dynamically through Settings.ACTION_MANAGE_OVERLAY_PERMISSION, which is set in Activity.
/ / MainActivity.ktfun startWindow (view: View?) {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 (Settings.canDrawOverlays (this)) {Toast.makeText (this, "floating window permission granted successfully", Toast.LENGTH_SHORT) .show () startService (Intent (this@MainActivity, FloatingWindowService::class.java))}} 3.3 complete code
Class FloatingWindowService: Service () {private lateinit var windowManager: WindowManager private lateinit var layoutParams: WindowManager.LayoutParams private lateinit var tvContent: AppCompatTextView private lateinit var handler: Handler private var receiver: MyReceiver? = null private var floatingView: View? = null privateval stringBuilder = StringBuilder () private var x = 0 private var y = 0 / / is used to determine whether floatingView is attached to window manager Prevent secondary removeView from crashing private var attached = false override fun onCreate () {super.onCreate () / / register broadcast receiver = MyReceiver () val filter = IntentFilter () filter.addAction ("android.intent.action.MyReceiver") registerReceiver (receiver, filter) / / get windowManager and set layoutParams windowManager = getSystemService (WINDOW_SERVICE) as WindowManager layoutParams = WindowManager.LayoutParams (). Apply {type = if (Build.VERSION.SDK_INT > = Build.VERSION_CODES.O) {WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY} else {WindowManager.LayoutParams.TYPE_PHONE} Format = PixelFormat.RGBA_8888// format = PixelFormat.TRANSPARENT gravity = Gravity.START or Gravity.TOP flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE width = 600height = 600x = 300y = 300} handler = Handler (this.mainLooper) {msg-> TvContent.text = msg.obj as String / / automatically scrolls when the text is beyond the screen Make sure the text is at the bottom val offset = tvContent.lineCount * tvContent.lineHeight floatingView?.apply {if (offset > height) {tvContent.scrollTo (0) Offset-height)}} false}} override fun onBind (intent: Intent?): IBinder? {return null} @ SuppressLint ("ClickableViewAccessibility") override fun onStartCommand (intent: Intent?, flags: Int StartId: Int): Int {if (Settings.canDrawOverlays (this)) {floatingView = LayoutInflater.from (this) .propagate (R.layout.layout_show_log Null) tvContent = floatingViewById (R.id.tv_log) floatingViewById (R.id.iv_close) .findViewById (R.id.iv_close). SetOnClickListener {stringBuilder.clear () windowManager.removeView (floatingView) attached = false} / / set TextView scroll tvContent.movementMethod = ScrollingMovementMethod.getInstance ( ) floatingViewById (R.id.layout_drag) .findViewById. SetOnTouchListener {v Event-> when (event.action) {MotionEvent.ACTION_DOWN-> {x = event.rawX.toInt () y = event.rawY.toInt ()} MotionEvent.ACTION_MOVE-> {val CurrentX = event.rawX.toInt () val currentY = event.rawY.toInt () val offsetX = currentX-x val offsetY = currentY-y x = currentX y = currentY layoutParams.x = layoutParams.x + offsetX LayoutParams.y = layoutParams.y + offsetY windowManager.updateViewLayout (floatingView LayoutParams)} true} windowManager.addView (floatingView, layoutParams) attached = true} return super.onStartCommand (intent, flags) StartId)} override fun onDestroy () {/ / Log out of the broadcast and delete floating window unregisterReceiver (receiver) receiver = null if (attached) {windowManager.removeView (floatingView)}} inner class MyReceiver: BroadcastReceiver () {override fun onReceive (context: Context) Intent: Intent) {val content = intent.getStringExtra ("content"): "" stringBuilder.append (content) .append ("\ n") val message = Message.obtain () message.what = 0 message.obj = stringBuilder.toString () handler.sendMessage (message)} above are all the contents of the article "how to achieve a suspension window in Android" Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.