android 應用內(nèi)部懸浮可拖動按鈕簡單實現(xiàn)代碼
本文介紹了android 應用內(nèi)部懸浮可拖動按鈕簡單實現(xiàn)代碼,分享給大家,具體如下:
可以懸浮在activity上面,在加載fragment時懸浮按鈕不會消失
實現(xiàn)方式很簡單,因為是在應用內(nèi)部拖動的,只需要通過Activity獲取WindowManager,然后將要拖動的view設置上去就行
設置代碼:
WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); //通過像素密度來設置按鈕的大小 dpi = dpi(dm.densityDpi); //屏寬 screenWidth = wm.getDefaultDisplay().getWidth(); //屏高 screenHeight = wm.getDefaultDisplay().getHeight(); //布局設置 wmParams = new WindowManager.LayoutParams(); // 設置window type wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION; wmParams.format = PixelFormat.RGBA_8888; // 設置圖片格式,效果為背景透明 wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 設置Window flag wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; wmParams.width = dpi; wmParams.height = dpi; wmParams.y = (screenHeight - dpi) >> 1; wm.addView(this, wmParams);
控件的大小根據(jù)像素密度來進行設置的
/** * 根據(jù)密度選擇控件大小 * */ private int dpi(int densityDpi) { if (densityDpi <= 120) { return 36; } else if (densityDpi <= 160) { return 48; } else if (densityDpi <= 240) { return 72; } else if (densityDpi <= 320) { return 96; } return 108; }
主要的處理問題就是控件的拖動問題,通過重寫onTouchEvent方法進行處理
源碼:
import android.app.Activity; import android.content.Context; import android.graphics.PixelFormat; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.RelativeLayout; import android.widget.TextView; /** * Created by xiang on 2016/12/28. * * im懸浮窗視圖 */ public class ChatView extends RelativeLayout{ // 懸浮欄位置 private final static int LEFT = 0; private final static int RIGHT = 1; private final static int TOP = 3; private final static int BUTTOM = 4; private int dpi; private int screenHeight; private int screenWidth; private WindowManager.LayoutParams wmParams; private WindowManager wm; private float x, y; private float mTouchStartX; private float mTouchStartY; private boolean isScroll; public ChatView(Activity activity) { super(activity); LayoutInflater.from(activity).inflate(R.layout.view_chat, this); setBackgroundResource(R.drawable.chat_btn); wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); //通過像素密度來設置按鈕的大小 dpi = dpi(dm.densityDpi); //屏寬 screenWidth = wm.getDefaultDisplay().getWidth(); //屏高 screenHeight = wm.getDefaultDisplay().getHeight(); //布局設置 wmParams = new WindowManager.LayoutParams(); // 設置window type wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION; wmParams.format = PixelFormat.RGBA_8888; // 設置圖片格式,效果為背景透明 wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 設置Window flag wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; wmParams.width = dpi; wmParams.height = dpi; wmParams.y = (screenHeight - dpi) >> 1; wm.addView(this, wmParams); hide(); } /** * 根據(jù)密度選擇控件大小 * */ private int dpi(int densityDpi) { if (densityDpi <= 120) { return 36; } else if (densityDpi <= 160) { return 48; } else if (densityDpi <= 240) { return 72; } else if (densityDpi <= 320) { return 96; } return 108; } public void show() { if (isShown()) { return; } setVisibility(View.VISIBLE); } public void hide() { setVisibility(View.GONE); } public void destory() { hide(); wm.removeViewImmediate(this); } @Override public boolean onTouchEvent(MotionEvent event) { // 獲取相對屏幕的坐標, 以屏幕左上角為原點 x = event.getRawX(); y = event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // setBackgroundDrawable(openDrawable); // invalidate(); // 獲取相對View的坐標,即以此View左上角為原點 mTouchStartX = event.getX(); mTouchStartY = event.getY(); break; case MotionEvent.ACTION_MOVE: if (isScroll) { updateViewPosition(); } else { // 當前不處于連續(xù)滑動狀態(tài) 則滑動小于圖標1/3則不滑動 if (Math.abs(mTouchStartX - event.getX()) > dpi / 3 || Math.abs(mTouchStartY - event.getY()) > dpi / 3) { updateViewPosition(); } else { break; } } isScroll = true; break; case MotionEvent.ACTION_UP: // 拖動 if (isScroll) { autoView(); // setBackgroundDrawable(closeDrawable); // invalidate(); } else { // 當前顯示功能區(qū),則隱藏 // setBackgroundDrawable(openDrawable); // invalidate(); } isScroll = false; mTouchStartX = mTouchStartY = 0; break; } return true; } /** * 自動移動位置 */ private void autoView() { // 得到view在屏幕中的位置 int[] location = new int[2]; getLocationOnScreen(location); //左側 if (location[0] < screenWidth / 2 - getWidth() / 2) { updateViewPosition(LEFT); } else { updateViewPosition(RIGHT); } } /** * 手指釋放更新懸浮窗位置 * */ private void updateViewPosition(int l) { switch (l) { case LEFT: wmParams.x = 0; break; case RIGHT: int x = screenWidth - dpi; wmParams.x = x; break; case TOP: wmParams.y = 0; break; case BUTTOM: wmParams.y = screenHeight - dpi; break; } wm.updateViewLayout(this, wmParams); } // 更新浮動窗口位置參數(shù) private void updateViewPosition() { wmParams.x = (int) (x - mTouchStartX); //是否存在狀態(tài)欄(提升滑動效果) // 不設置為全屏(狀態(tài)欄存在) 標題欄是屏幕的1/25 wmParams.y = (int) (y - mTouchStartY - screenHeight / 25); wm.updateViewLayout(this, wmParams); } }
使用方法:
//傳入上下文Activity ChatView chatView = new ChatView(this); chatView.show();
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- android 添加隨意拖動的桌面懸浮窗口
- Android 可拖動的seekbar自定義進度值
- Android 仿淘寶、京東商品詳情頁向上拖動查看圖文詳情控件DEMO詳解
- android Matrix實現(xiàn)圖片隨意放大縮小或拖動
- Android 實現(xiàn)可任意拖動的懸浮窗功能(類似懸浮球)
- Android實現(xiàn)ImageView圖片縮放和拖動
- Android實現(xiàn)跟隨手指拖動并自動貼邊的View樣式(實例demo)
- Android編程之控件可拖動的實現(xiàn)方法
- Android自定義垂直拖動seekbar進度條
- Android自定義View實現(xiàn)拖動自動吸邊效果
相關文章
React?Native之在Android上添加陰影的實現(xiàn)
這篇文章主要介紹了React?Native之在Android上添加陰影的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03Android開發(fā)實現(xiàn)跟隨手指的小球效果示例
這篇文章主要介紹了Android開發(fā)實現(xiàn)跟隨手指的小球效果,涉及Android圖形繪制、事件響應、界面布局等相關操作技巧,需要的朋友可以參考下2019-04-04Android開發(fā)實現(xiàn)的IntentUtil跳轉多功能工具類【包含視頻、音頻、圖片、攝像頭等操作功能】
這篇文章主要介紹了Android開發(fā)實現(xiàn)的IntentUtil跳轉多功能工具類,該封裝類還包含視頻、音頻、圖片、攝像頭等操作功能,需要的朋友可以參考下2017-11-11Android實現(xiàn)調用手機攝像頭錄像限制錄像時長
這篇文章主要為大家詳細介紹了Android實現(xiàn)調用手機攝像頭錄像限制錄像時長,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03Kotlin自定義實現(xiàn)支付密碼數(shù)字鍵盤的方法實例
這篇文章主要給大家介紹了關于Kotlin如何自定義實現(xiàn)支付密碼數(shù)字鍵盤的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-07-07Eclipse打開時“發(fā)現(xiàn)了以元素''d:skin''”開頭的無效內(nèi)容。此處不應含有子元素的解決方法
這篇文章主要介紹了Eclipse打開時“發(fā)現(xiàn)了以元素'd:skin'”開頭的無效內(nèi)容。此處不應含有子元素的解決方法,涉及Android sdk中devices.xml文件的修改,需要的朋友可以參考下2016-01-01