日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

2022-10-10 Android 在其他应用上的悬浮窗View

發(fā)布時(shí)間:2023/12/10 Android 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2022-10-10 Android 在其他应用上的悬浮窗View 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、在samsung android8.0 真機(jī)運(yùn)行效果圖如下


二、廢話不多說,直接上代碼

? ? 1、代碼架構(gòu)

? ? 2、java/com/example/suspendedwindow/MainActivity.java

package com.example.suspendedwindow;import androidx.appcompat.app.AppCompatActivity;import java.util.Timer; import java.util.TimerTask;import android.annotation.SuppressLint; import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast;/*** 倒計(jì)時(shí)60s懸浮窗** @author zy**/ public class MainActivity extends Activity {protected static final String TAG = "CountDownActivity";protected static final int TIME = 1;private Context context = MainActivity.this;private TextView tv_time;private Button cancle;private static Timer countDown = null;private int mValue = 60;private int statusBarHeight;// 狀態(tài)欄高度WindowManager wm;WindowManager.LayoutParams params ;View countDownView;private boolean viewAdded = false;// 透明窗體是否已經(jīng)顯示//private WindowManager.LayoutParams layoutParams ;Handler post = new Handler();LinearLayout commonCardContainer;LinearLayout.LayoutParams params_window;int width = 10;boolean lock = false ;int remeberx = 0;int remebery = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}/*** 點(diǎn)擊顯示懸浮窗** @param*/@SuppressLint("WrongConstant")public void show(View v) {wm = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE); // 注意:這里必須是全局的context// 判斷UI控件是否存在,存在則移除,確保開啟任意次應(yīng)用都只有一個(gè)懸浮窗if (countDownView != null) {wm.removeView(countDownView);}/*params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); */params = new WindowManager.LayoutParams();params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;// 系統(tǒng)級別的窗口params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;//| WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY// params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;// 居中顯示// params.gravity = Gravity.CENTER;//params.gravity = Gravity.RIGHT|Gravity.BOTTOM; //懸浮窗開始在右下角顯示params.gravity = Gravity.LEFT | Gravity.TOP;// 設(shè)置背景透明params.format = PixelFormat.TRANSPARENT;countDownView = new View(getApplicationContext()); // 不依賴activity的生命周期countDownView = View.inflate(getApplicationContext(),R.layout.countdown_weight, null);cancle = (Button) countDownView.findViewById(R.id.cancle);tv_time = (TextView) countDownView.findViewById(R.id.tv_time);tv_time.setText("60");wm.addView(countDownView, params);viewAdded = true;/*** 監(jiān)聽窗體移動事件*/countDownView.setOnTouchListener(new View.OnTouchListener() {float[] temp = new float[] { 0f, 0f };public boolean onTouch(View v, MotionEvent event) {Log.i(TAG, "temp[0]:" + temp[0]+" temp[1]:" + temp[1] + " X:" + event.getX()+" Y:"+event.getY() + " RawX:"+event.getRawX() + " RawY:"+event.getRawY());if(lock)return true;int eventaction = event.getAction();switch (eventaction) {case MotionEvent.ACTION_DOWN: // 按下事件,記錄按下時(shí)手指在懸浮窗的XY坐標(biāo)值temp[0] = event.getX();temp[1] = event.getY();break;case MotionEvent.ACTION_MOVE:refreshView((int) (event.getRawX() - temp[0]),(int) (event.getRawY() - temp[1]));break;}return true;}});// 設(shè)置“取消”倒計(jì)時(shí)按鈕的監(jiān)聽cancle.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {/*Log.e(TAG, "取消倒計(jì)時(shí)");wm.removeView(countDownView);countDownView = null;countDown.cancel();mValue = 999;*/ /*ImageView twenty_four_hour = (ImageView) countDownView.findViewById(R.id.img);LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) twenty_four_hour.getLayoutParams();lp.width = ++lp.width;twenty_four_hour.setLayoutParams(lp);Log.i(TAG, "lp.width:"+lp.width); */lock = !lock;if(lock){Toast.makeText(MainActivity.this, "Locked", Toast.LENGTH_SHORT).show();params.flags = 0 ;refresh();}else {Toast.makeText(MainActivity.this, "Unocked", Toast.LENGTH_SHORT).show();params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;refresh();}}});// 添加倒計(jì)時(shí)功能countDown = new Timer();countDown.schedule(new TimerTask() {@Overridepublic void run() {mValue--;post.post(drawCount);if (mValue == 0) {// 執(zhí)行關(guān)機(jī)操作(這里可以使任意其他操作,根據(jù)自己的需求)Log.e(TAG, "關(guān)機(jī)");wm.removeView(countDownView);countDownView = null;// 取消定時(shí)countDown.cancel();finish();}}}, 0, 1000);// refreshView(295, 949);finish();}private void refreshView(int x, int y) {// 狀態(tài)欄高度不能立即取,不然得到的值是0if (statusBarHeight == 0) {View rootView = countDownView.getRootView();Rect r = new Rect();rootView.getWindowVisibleDisplayFrame(r);statusBarHeight = r.top;}params.x = x;// y軸減去狀態(tài)欄的高度,因?yàn)闋顟B(tài)欄不是用戶可以繪制的區(qū)域,不然拖動的時(shí)候會有跳動params.y = y - statusBarHeight;// STATUS_HEIGHT;Log.i(TAG, " x:"+x+" y:"+y+" params.x:"+params.x+" params.y:" +params.y +" statusBarHeight:"+statusBarHeight);// params.x = 1080- params.x;// params.y = 1920- params.y;//params.x = 311 ;//params.y = 1114 ;remeberx = params.x;remebery = params.y;refresh(); /*ImageView twenty_four_hour = (ImageView) countDownView.findViewById(R.id.img);LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) twenty_four_hour.getLayoutParams();twenty_four_hour.setLayoutParams(lp);Log.i(TAG, "lp.width:"+lp.width);*/}/*** 添加懸浮窗或者更新懸浮窗 如果懸浮窗還沒添加則添加 如果已經(jīng)添加則更新其位置*/private void refresh() {// 如果已經(jīng)添加了就只更新viewif (viewAdded) {wm.updateViewLayout(countDownView, params);} else {wm.addView(countDownView, params);viewAdded = true;}}/*** 模擬其他操作* @param view*/public void other(View view) {Toast.makeText(context, "別的操作", Toast.LENGTH_SHORT).show();ImageView twenty_four_hour = (ImageView) findViewById(R.id.img);RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) twenty_four_hour.getLayoutParams();lp.width = lp.width + 1;twenty_four_hour.setLayoutParams(lp);Log.i(TAG, "lp.width:"+lp.width+ " topMargin:"+lp.topMargin);// startActivity(new Intent(context, NewActivity.class));}Runnable drawCount = new Runnable() {@Overridepublic void run() {tv_time.setText(Integer.toString(mValue));}};@Overrideprotected void onDestroy() {super.onDestroy();Log.e(TAG, "倒計(jì)時(shí)結(jié)束");}; }

? ? 3、res/layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" ><ImageViewandroid:id="@+id/img"android:layout_width="152px"android:layout_height="wrap_content"android:layout_marginTop="126px"android:text="60"android:textColor="#ff0000"android:background="@drawable/background"android:textSize="25dp" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="show"android:text="點(diǎn)擊顯示彈窗" /><Buttonandroid:layout_alignParentBottom="true"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="other"android:text="別的操作" /></RelativeLayout>

? ? 4、res/layout/countdown_weight.xml

<?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"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/twenty_four_hour"android:layout_gravity="center"android:gravity="center_horizontal"android:orientation="vertical"android:padding="10dp" ><ImageViewandroid:id="@+id/img"android:layout_width="433px"android:layout_height="290px"android:text="60"android:textColor="#ff0000"android:background="@drawable/background"android:textSize="25dp" /><TextViewandroid:id="@+id/tv_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="60"android:textColor="#ff0000"android:textSize="25dp" /><Buttonandroid:id="@+id/cancle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="取消"android:textSize="25dp"android:textColor="#000" /><!-- android:background="@drawable/xml_sel_button_bg" --></LinearLayout></FrameLayout>

? ? 5、申請權(quán)限

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

? ? 6、遇到的一個(gè)坑

?

三、參考文章

(664條消息) Android懸浮窗看這篇就夠了_AndroidLMY的博客-CSDN博客_android 懸浮窗

(664條消息) Android懸浮窗的坑_android_cai_niao的博客-CSDN博客_android studio 懸浮窗

(664條消息) Android常用控件之懸浮窗_dztai的博客-CSDN博客_安卓懸浮窗

(664條消息) Android懸浮窗的實(shí)現(xiàn)--可以置頂,可以設(shè)置優(yōu)先級的view_兮誰與歌的博客-CSDN博客_倒計(jì)時(shí)懸浮窗

總結(jié)

以上是生活随笔為你收集整理的2022-10-10 Android 在其他应用上的悬浮窗View的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。