android程式設計之懸浮窗體
用過手機360和QQ手機管家等一些軟體的朋友,會發現,在這些應用中,會出現一個懸浮窗體,例如QQ手機管家中打電話的場景:
這種窗體除了會顯示外,還可以移動它的位置,並且一直顯示。除了關閉當前程式外,視窗不會主動消失。其實,它的使用原理也很簡單,就是借用了WindowManager這個管理類來實現的。
注意:要在AndroidManifest.xml中新增使用許可權:
<uses-permission
android:name="android.permission.SYSTEM_ALERT_WINDOW" />
這裡,我採用程式碼佈局的方式,模仿了一下QQ這個介面效果:
import android.content.Context; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class DesktopLayout extends LinearLayout { public DesktopLayout(Context context) { super(context); setOrientation(LinearLayout.HORIZONTAL); LayoutParams mLayoutParams = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); setLayoutParams(mLayoutParams); // 顯示的ICON ImageView mImageView = new ImageView(context); mImageView.setImageResource(R.drawable.icon); addView(mImageView, mLayoutParams); // 顯示的文字 TextView mTextView = new TextView(context); mTextView.setText("Hello"); mTextView.setTextSize(30); addView(mTextView, mLayoutParams); } }
接下來,在activity中讓它顯示出來。首先要設定一下WindowManager.LayoutParams:
// 取得系統窗體 mWindowManager = (WindowManager) getApplicationContext() .getSystemService("window"); // 窗體的佈局樣式 mLayoutParams = new WindowManager.LayoutParams(); // 設定窗體顯示型別——TYPE_SYSTEM_ALERT(系統提示) mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 設定窗體焦點及觸控: // FLAG_NOT_FOCUSABLE(不能獲得按鍵輸入焦點) mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 設定顯示的模式 mLayoutParams.format = PixelFormat.RGBA_8888; // 設定對齊的方法 mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT; // 設定窗體寬度和高度 mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; // 設定窗體顯示的位置,否則在螢幕中心顯示 mLayoutParams.x = 50; mLayoutParams.y = 50;
顯示窗體與關閉窗體的方法:
mWindowManager.addView(mDesktopLayout, mLayoutParams);
mWindowManager.removeView(mDesktopLayout);
以下是activity的原始碼,這裡設計了一個雙擊關閉窗體的效果:
import android.app.Activity; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.WindowManager; import android.widget.Button; public class DeskTip extends Activity { private WindowManager mWindowManager; private WindowManager.LayoutParams mLayoutParams; private DesktopLayout mDesktopLayout; private long starttime; /** * 建立懸浮窗體 */ private void createDesktopLayout() { mDesktopLayout = new DesktopLayout(this); mDesktopLayout.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { onActionMove(event); return true; } }); } /** * 設定WindowManager */ private void createWindowManager() { // 取得系統窗體 mWindowManager = (WindowManager) getApplicationContext() .getSystemService("window"); // 窗體的佈局樣式 mLayoutParams = new WindowManager.LayoutParams(); // 設定窗體顯示型別——TYPE_SYSTEM_ALERT(系統提示) mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 設定窗體焦點及觸控: // FLAG_NOT_FOCUSABLE(不能獲得按鍵輸入焦點) mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 設定顯示的模式 mLayoutParams.format = PixelFormat.RGBA_8888; // 設定對齊的方法 mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT; // 設定窗體寬度和高度 mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; // 設定窗體顯示的位置,否則在螢幕中心顯示 mLayoutParams.x = 50; mLayoutParams.y = 50; } private void onActionMove(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { long end = System.currentTimeMillis() - starttime; // 雙擊的間隔在 200ms 到 500ms 之間 if (end > 200 && end < 500) { closeDesk(); return; } starttime = System.currentTimeMillis(); } mLayoutParams.x = (int) (event.getRawX() - (mDesktopLayout.getWidth())); mLayoutParams.y = (int) (event.getRawY() - (mDesktopLayout.getHeight())); mWindowManager.updateViewLayout(mDesktopLayout, mLayoutParams); } /** * 顯示DesktopLayout */ private void showDesk() { mWindowManager.addView(mDesktopLayout, mLayoutParams); finish(); } /** * 關閉DesktopLayout */ private void closeDesk() { mWindowManager.removeView(mDesktopLayout); finish(); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); createWindowManager(); createDesktopLayout(); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { showDesk(); } }); } }
顯示的效果:
懸浮窗體例子
相關推薦
android程式設計之懸浮窗體
用過手機360和QQ手機管家等一些軟體的朋友,會發現,在這些應用中,會出現一個懸浮窗體,例如QQ手機管家中打電話的場景: 這種窗體除了會顯示外,還可以移動它的位置,並且一直顯示。除了關閉當前程式外,視窗不會主動消失。其實,它的使用原理也很簡單,就是借用了WindowMana
Android程式設計之指定ListView的item位置
很多情況,我們需要指定ListView中顯示Item的位置,如:當前已經滾動到後面,然後響應某個事件,要ListView回到頭部。 程式碼如下,其中mListView為ListView的物件: private void setListViewPos(int pos
Android程式設計之Listener偵聽的N種寫法及實現原理
寫下這個題目時突然想起魯迅筆下的孔乙已,茴香豆的幾種寫法,頗有些咬文嚼字的味道。雖然從事手機程式設計多年,但一直使用的是C和C++程式設計,由於安卓早期只支援JAVA開發,所以對於時下如火如荼的安卓系統,我一直觀之而未入之。現在由於工作需要開始研究安卓程式設計,由於以前主要使
Android程式設計:懸浮選單按鈕FloatingActionButton例項
Android程式設計:懸浮選單按鈕FloatingActionButton例項環境:主機:WIN10開發環境:Android Studio 2.2 Preview 3說明:用第三方庫FloatingActionButton實現懸浮選單按鈕效果圖:佈局:<?xml ve
android程式設計之圖形繪製
android課堂作業要求做個五子棋遊戲,想想如果直接用控制元件可能速度會比較慢,因此就想用比較常規的遊戲程式設計方法,螢幕繪製.今天查了些資料,並做個整理. 跟其他的螢幕繪製機制一樣,android
Android程式設計之DialogFragment原始碼詳解(一)
DialogFragment是Fragment家族成員之一,如果你把它簡單的理解成Dialog,那就錯了。它的確可以做作dialog顯示,還可以顯示出自己定義的Dialog或者AlertDialog,但它同時也是一個Fragment。 按照官方的話來理解就是,你既可以把它當
Android程式設計之Fragment使用動畫造成Unknown animation name: objectAnimator異常
在為Fragment做切換動畫,啟動後遇到了一個異常: Caused by: java.lang.RuntimeException: Unknown animation name: objectAnimator 截圖如下: 我的程式碼如下: fragment
Android程式設計之仿微信顯示更多文字的View
微信朋友圈中,如果好友發表的文字過長,會自動收縮起來,底下有提示,當點選“顯示更多”時才會展開。 首先定義佈局檔案(很簡單,不解釋): <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:
體驗Android程式設計之美
因為公司業務是做行情的,一般的短連線達不到這種頻繁更新資料的需求,所以長連線是必不可少的。 當下比較流行的三方框架我覺得就屬Mars了,多平臺都可以使用,而且最主要的是微信官方開源,瞬間逼格就上去了,在網路質量、日誌列印這些方面表現相對比較突出,所以就決定用M
Android 程式設計之天氣預報下來重新整理資料及城市容器配置--3
前面已經把活動和服務講了講,要注意的是服務的用法,我們在這裡是 extends IntentService implements LocationListener ,下面看下 IntentService IntentService是一個通過Context.startSer
Android開發之仿手機衛士懸浮窗效果
wrap 使用 indexof handle post ani refresh stat gen 基本的實現原理,這種桌面懸浮窗的效果很類似與Widget,但是它比Widget要靈活的多。主要是通過WindowManager這個類來實現的,調用這個類的addView方法用於
Android 學習之《Android程式設計權威指南》第二版 程式碼+筆記整理(四)
(程式碼)GeoQuiz最終開發 GeoQuiz應用初步開發 GeoQuiz應用升級開發 解決GeoQuiz應用旋轉恢復第一題的BUG 不展示編譯器自動完成的程式碼,僅提供手動修改或者編寫的程式碼。 省略了先前一些程式碼,可參照上方連結。 升級內容: 增加作弊按鈕,給使用者提
Android響應式程式設計之RxJava2.0
前言 優點: 1、鏈式操作 2、非同步優化 實戰 先來個簡單的使用示例 Observable .create(new ObservableOnSubscribe<String>() {
android程式設計3 socket程式設計之udp傳送
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
如何實現android中監聽來電並生成懸浮窗體提示
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android 學習之《Android程式設計權威指南》第二版 程式碼+筆記整理(三)
(程式碼)解決GeoQuiz應用旋轉恢復第一題的BUG 一、產生BUG的原因 1. 裝置旋轉時,系統會銷燬當前的QuizActivity例項,然後建立一個新的例項,這時陣列索引(mCurrentIndex)會初始化為0,因此使用者看到的還是第一道題目。 2.
安全程式設計之Android APK打包程式碼混淆
第一步:在專案工程目錄下的proguard-rules.pro檔案中配置自定義的混淆規則 #注意: #1.引用外部的jar包 如果不是自己寫的最好不混淆它們,因為外部jar包有可能已經混淆過 #2.不要混淆XML佈局中使用的自定義控制元件類,混淆後加載佈局會報找不到該控制
Android 多執行緒程式設計之 HandlerThread 詳解
HandlerThread有那些特點: HandlerThread本質上是一個執行緒類,它繼承了Thread; HandlerThread有自己的內部Looper物件,可以進行looper迴圈; 通過獲取HandlerThread的looper物件傳
Android網路程式設計之socket和http程式設計的區別
HTTP為短連線 Http協議是建立在TCP協議之上的一種應用。它與TCP連線不同之處在於,客戶端每次請求都需要伺服器返回響應,在請求結束後,會主動釋放連線,從建立連線到關閉連線的過程稱為“一次連線”。由於HTTP每次請求都會釋放連線,因為
Android網路程式設計之傳遞資料給伺服器(二)
我曾在《Android網路程式設計之傳遞資料給伺服器(一) 》一文中介紹瞭如何通過GET方式傳遞資料給伺服器,通過GET方式傳遞資料主要適用於資料大小不超過2KB,且對安全性要求不高的情況下。下面就介紹通過POST方式傳遞資料主到伺服器。 一、通過P