android 浮動文字提示,Android實現自由拖動并顯示文字的懸浮框

項目中需要實現一個狀態顯示的懸浮框,要求可以設置兩種模式:拖動模式和不可拖動模式。

實現效果圖如下:

5ab379003aa852009b8a2e05a309dbb3.gif

實現步驟:

1.首先要設置該懸浮框的基本屬性:

/**

* 顯示彈出框

*

* @param context

*/

@SuppressWarnings("WrongConstant")

public static void showPopupWindow(final Context context, String showtxt) {

if (isShown) {

return;

}

isShown = true;

// 獲取WindowManager

mWindowManager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

mView = setUpView(context, showtxt);

params = new WindowManager.LayoutParams();

// 類型,系統提示以及它總是出現在應用程序窗口之上。

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

// 設置flag

int flags = canTouchFlags;

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 如果設置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,彈出的View收不到Back鍵的事件

params.flags = flags;

// 不設置這個彈出框的透明遮罩顯示為黑色

params.format = PixelFormat.TRANSLUCENT;

// FLAG_NOT_TOUCH_MODAL不阻塞事件傳遞到后面的窗口

// 設置 FLAG_NOT_FOCUSABLE 懸浮窗口較小時,后面的應用圖標由不可長按變為可長按

// 不設置這個flag的話,home頁的劃屏會有問題

params.width = LayoutParams.WRAP_CONTENT;

params.height = LayoutParams.WRAP_CONTENT;

params.gravity = Gravity.TOP;

mWindowManager.addView(mView, params);

}

比較重要的點是要注意設置flags,我這里提供了兩種flags以供切換:

private static int canTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

private static int notTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

第一種是可觸摸不可聚焦模式,第二種是不可觸摸不可聚焦模式。其他的flags可以從api中查閱。

2.設置懸浮框的拖動監聽事件:

private static View setUpView(final Context context, String showtxt) {

View view = LayoutInflater.from(context).inflate(R.layout.layout_popwindow,

null);

TextView showTv = (TextView) view.findViewById(R.id.tv_showinpop);

showTv.setText(showtxt);

rl_drag_showinpop = (RelativeLayout) view.findViewById(R.id.rl_drag_showinpop);

rl_drag_showinpop.setOnTouchListener(new View.OnTouchListener() {

private float lastX; //上一次位置的X.Y坐標

private float lastY;

private float nowX; //當前移動位置的X.Y坐標

private float nowY;

private float tranX; //懸浮窗移動位置的相對值

private float tranY;

@Override

public boolean onTouch(View v, MotionEvent event) {

boolean ret = false;

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

// 獲取按下時的X,Y坐標

lastX = event.getRawX();

lastY = event.getRawY();

ret = true;

break;

case MotionEvent.ACTION_MOVE:

// 獲取移動時的X,Y坐標

nowX = event.getRawX();

nowY = event.getRawY();

// 計算XY坐標偏移量

tranX = nowX - lastX;

tranY = nowY - lastY;

params.x += tranX;

params.y += tranY;

//更新懸浮窗位置

mWindowManager.updateViewLayout(mView, params);

//記錄當前坐標作為下一次計算的上一次移動的位置坐標

lastX = nowX;

lastY = nowY;

break;

case MotionEvent.ACTION_UP:

break;

}

return ret;

}

});

這里要在down的時候記錄坐標,move事件中使用修改params坐標進行移動。

3.設置懸浮框文字屬性:

public static void setShowTxt(String txt) {

try {

TextView showTv = (TextView) mView.findViewById(R.id.tv_showinpop);

showTv.setText(txt);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新懸浮框錯誤");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

4.更新懸浮框圖片顯示:

public static void setShowImg(Bitmap bitmap) {

try {

ImageView showImg = (ImageView) mView.findViewById(R.id.iv_showinpop);

showImg.setImageBitmap(bitmap);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新懸浮框錯誤");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

介紹完畢,整個類都封裝好了,代碼如下:

/**

* 懸浮窗工具類

* created by Pumpkin at 17/3/28

*/

public class WindowsUitlity {

private static String TAG = WindowsUitlity.class.getSimpleName();

private static WindowManager mWindowManager = null;

private static WindowManager.LayoutParams params;

public static Boolean isShown = false;

private static View mView = null;

/**

* 顯示彈出框

*

* @param context

*/

@SuppressWarnings("WrongConstant")

public static void showPopupWindow(final Context context, String showtxt) {

if (isShown) {

return;

}

isShown = true;

// 獲取WindowManager

mWindowManager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

mView = setUpView(context, showtxt);

params = new WindowManager.LayoutParams();

// 類型,系統提示以及它總是出現在應用程序窗口之上。

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

// 設置flag

int flags = canTouchFlags;

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 如果設置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,彈出的View收不到Back鍵的事件

params.flags = flags;

// 不設置這個彈出框的透明遮罩顯示為黑色

params.format = PixelFormat.TRANSLUCENT;

// FLAG_NOT_TOUCH_MODAL不阻塞事件傳遞到后面的窗口

// 設置 FLAG_NOT_FOCUSABLE 懸浮窗口較小時,后面的應用圖標由不可長按變為可長按

// 不設置這個flag的話,home頁的劃屏會有問題

params.width = LayoutParams.WRAP_CONTENT;

params.height = LayoutParams.WRAP_CONTENT;

params.gravity = Gravity.TOP;

mWindowManager.addView(mView, params);

}

private static int canTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

private static int notTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

/**

* 設置是否可響應點擊事件

*

* @param isTouchable

*/

public static void setTouchable(boolean isTouchable) {

if (isTouchable) {

params.flags = canTouchFlags;

} else {

params.flags = notTouchFlags;

}

mWindowManager.updateViewLayout(mView, params);

}

/**

* 隱藏彈出框

*/

public static void hidePopupWindow() {

if (isShown && null != mView) {

mWindowManager.removeView(mView);

isShown = false;

}

}

public static void setShowTxt(String txt) {

try {

TextView showTv = (TextView) mView.findViewById(R.id.tv_showinpop);

showTv.setText(txt);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新懸浮框錯誤");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

public static void setShowImg(Bitmap bitmap) {

try {

ImageView showImg = (ImageView) mView.findViewById(R.id.iv_showinpop);

showImg.setImageBitmap(bitmap);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新懸浮框錯誤");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

static RelativeLayout rl_drag_showinpop;

private static View setUpView(final Context context, String showtxt) {

View view = LayoutInflater.from(context).inflate(R.layout.layout_popwindow,

null);

TextView showTv = (TextView) view.findViewById(R.id.tv_showinpop);

showTv.setText(showtxt);

rl_drag_showinpop = (RelativeLayout) view.findViewById(R.id.rl_drag_showinpop);

rl_drag_showinpop.setOnTouchListener(new View.OnTouchListener() {

private float lastX; //上一次位置的X.Y坐標

private float lastY;

private float nowX; //當前移動位置的X.Y坐標

private float nowY;

private float tranX; //懸浮窗移動位置的相對值

private float tranY;

@Override

public boolean onTouch(View v, MotionEvent event) {

boolean ret = false;

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

// 獲取按下時的X,Y坐標

lastX = event.getRawX();

lastY = event.getRawY();

ret = true;

break;

case MotionEvent.ACTION_MOVE:

// 獲取移動時的X,Y坐標

nowX = event.getRawX();

nowY = event.getRawY();

// 計算XY坐標偏移量

tranX = nowX - lastX;

tranY = nowY - lastY;

params.x += tranX;

params.y += tranY;

//更新懸浮窗位置

mWindowManager.updateViewLayout(mView, params);

//記錄當前坐標作為下一次計算的上一次移動的位置坐標

lastX = nowX;

lastY = nowY;

break;

case MotionEvent.ACTION_UP:

break;

}

return ret;

}

});

return view;

}

}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458852.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android4.2.2的Stagefright維護編解碼器的數據流

這里是他們自己的源代碼閱讀點滴總結屬性,轉請注明出處,謝謝。歡迎和大家分享。qq:1037701636 email:gzzaigcn2012gmail.comAndroid源代碼版本號Version:4.2.2; 硬件平臺 全志A31前沿:在前面的博文中,基本提到的是stag…

PHP的安裝

PHP的環境也是諸多服務器軟件的必要因素之一,它是一個HTML內嵌式語言,在服務器端執行。由于PHP的開源高效化平臺,所以搭建一個php環境是一個運維工程師必備的能力。現在lamp也有類似lnmp.org那種一鍵安裝包,地址是http://yumlamp.…

android 橫向鋪滿,Android開發全程記錄(八)——設置ImageView顯示的圖片鋪滿全屏(適應魅族等不常見屏幕比例)...

為適應不同屏幕的手機,ImageView顯示的圖片可能不鋪滿屏幕,如果定高的話,兩邊可能會出現空白。魅族手機就會有這種情況,在其他手機里顯示正常,在魅族手機里顯示,圖片左右兩邊會出現空白,為解決這…

tihs 關鍵字

//this關鍵詞/*調用類中的屬性 調用類中的方法或構造方法 調用當前對象,調用自己的方法,可以省略。 */ //http://blog.sina.com.cn/s/blog_71f6c1980100wtj4.html//this指當前對象自己public class Google{String s"hello";public Google(Stri…

良好的編程習慣

*************************************************** 更多精彩,歡迎進入:http://shop115376623.taobao.com *************************************************** 良好的編程習慣良好的習慣對于人的成長是非常重要的,良好的編程習慣對于我…

ntfs for mac使用注意事項有哪些?

2019獨角獸企業重金招聘Python工程師標準>>> mac的用戶有很多,一些用戶朋友會發現自己的電腦是無法讀寫ntfs驅動器的。而ntfs驅動器又是一種常用的驅動器。面對這種情況我們可以選擇用NTFS for Mac軟件來幫助我們,它可以讀寫ntfs驅動器&#…

android音樂播放器文章,Android復習09【內容提供者、音樂播放器】

目 錄PersonCpPersonCp.javainsert()ContentObserver音樂播放器1、添加讀寫權限1.1、動態權限授予(調用封裝好的方法)2、獲取音樂文件(MainActivity.java)2、Music.java(實體類)申請訪問SD卡的權限設置適配器下拉刷新PersonCpPersonCp.javapackage cn.wangzg.personcp;import a…

程序員的業余項目

程序員的業余項目&#xff0c;我們也叫它 side project。 前幾天&#xff0c;100offer 發起了一場活動叫 <尋找實干和堅持的技術力量>&#xff0c;他們是這么說的&#xff1a; 世界在被代碼改變著&#xff0c;而我們在創造著代碼。 僅僅是因為好玩&#xff0c;他開發了…

C語言的數組名和對數組名取地址

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 相信不少的C語言初學者都知道&#xff0c;數組名相當于指針&#xff0c;指向數組的首地…

小米 android 8,小米華為們誰最良心?10大手機廠商安卓8.0升級情況盤點

3月8日&#xff0c;谷歌放出了首個安卓9.0開發者預覽版的固件包&#xff0c;不出意外的話&#xff0c;它的正式版會在今年正式亮相。但對廣大安卓用戶來說&#xff0c;想要立刻用上最新系統并非易事。目前來說&#xff0c;安卓碎片化問題依然嚴重&#xff0c;我們不妨現實點&am…

窺探Swift之數組安全索引與數組切片

在Swift中的數組和字典中下標是非常常見的&#xff0c;數組可以通過索引下標進行元素的查詢&#xff0c;字典可以通過鍵下標來獲取相應的值。在使用數組時&#xff0c;一個常見的致命錯誤就是數組越界。如果在你的應用程序中數組越界了&#xff0c;那么對不起&#xff0c;如果由…

大小端模式的快速判斷方法

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 大小端的問題剖析&#xff1a; 嵌 入式系統開發者應該對Little-endian和Big-endian模…

【RAC】How to Proceed from Failed 11gR2 CRS Installation

Applies to: [ID 942166.1] Oracle Server – Enterprise Edition – Version: 11.2.0.1 to 11.2.0.2 – Release: 11.2 to 11.2 Generic UNIX Generic Linux Goal This goal of this note is to provide steps to proceed from failed 11gR2 Grid Infrastructure installat…

WinForm支持拖拽效果

有一個MSDN客戶提問在WinForm中如何實現拖拽效果——比如在WinForm中有一個Button&#xff0c;我要實現的效果是拖拽這個Button到目標位置后生成一個該控件的副本。 其實這個操作主要分成三步走&#xff1a; 1&#xff09;確定被拖拽的對象&#xff1a; 這里是Button&#xff0…

win7 64位出現桌面右鍵鼠標顯示忙碌

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 將下面綠色內容復制到txt文本中&#xff0c;然后另存為1.bat 雙擊運行即可 【針對64位…

android tee,Android 9.0的新增安全特性與TEE

Android P&#xff0c;預計將于 2018 年第三季度發布最終版本。特別是Android8.0以來&#xff0c;安全性是Android版本變更的一個重要因素。從安全性增強方面來看&#xff0c;本次Android9.0版本主要有以下幾個方面&#xff1a;統一的指紋身份驗證對話框Android P 中&#xff0…

哪些要素會讓咱們呈現抑郁癥的病癥

依據最新研討標明&#xff0c;一自個的性情怎樣&#xff0c;本來是天然生成的&#xff0c;后天的日子&#xff0c;僅僅對咱們的性情進行批改&#xff0c;但在咱們潛意識中&#xff0c;違反自個性情的行動&#xff0c;會讓咱們感到格外累&#xff0c;所以&#xff0c;不少人即是…

如何定義一個只能在堆上(棧上)生成對象的類?

在C中&#xff0c;類的對象建立分為兩種&#xff0c;一種是靜態建立&#xff0c;如A a&#xff1b;另一種是動態建立&#xff0c;如A* ptrnew A&#xff1b;這兩種方式是有區別的。 靜態建立一個類對象&#xff0c;是由編譯器為對象在棧空間中分配內存&#xff0c;是通過直接移…

canny算子的理論分析

****************************************************************************************************************************************** 紅&#xff1a;數字圖像處理視頻教程&#xff08;兩部&#xff09; {中科院版36講視頻教程 電子科大版70講視頻教程&#x…

Android為spinner設置適配器,Android Spinner與適配器模式詳解及實例代碼

最近做項目對Android Spinner 使用&#xff0c;這里簡單寫個小例子&#xff0c;來測試如何使用。Spinner是一個下拉列表&#xff0c;往安卓界面中拖拽一個Spinner控件&#xff0c;在屬性中設置Android:entries“array/spinner_data”其中spinner_data為在string中設置的數組。數…