Android悬浮球和悬浮条的开发
一般做sdk都需要我们做一个可拖拽的悬浮球,点击悬浮球展示悬浮条 (无需任何权限!!!)
调用代码
public class MainActivity extends AppCompatActivity {
private MyFloatView myFloatView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
}
public void dismiss(View view) {
if (myFloatView != null)
myFloatView.dismiss();
}
public void show(View view) {
if (myFloatView == null){
myFloatView = new MyFloatView(this,true);
}
myFloatView.show();
}
}
布局代码 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<View
android:onClick="show"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<View
android:background="@color/black"
android:layout_width="3dp"
android:layout_height="match_parent"/>
<View
android:onClick="dismiss"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
layout_left_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@android:drawable/ic_input_get" />
<ImageView
android:id="@+id/iv_left_one"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@android:drawable/ic_menu_compass" />
</LinearLayout>
layout_right_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:visibility="visible">
<ImageView
android:id="@+id/iv_right_one"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@android:drawable/ic_menu_compass" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@android:drawable/ic_input_get" />
</LinearLayout>
> MyFloatView.java
```java
package com.example.myapplication;
import android.app.Service;
import android.content.Context;
import android.graphics.PixelFormat;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
public class MyFloatView extends LinearLayout {
private WindowManager wm;
private WindowManager.LayoutParams floatParams;
private boolean isShowFloatBar;
private boolean isFloatShow;
private float downX;
private float downY;
private int screenW;
private int screenH;
private LinearLayout leftMenu;
private LinearLayout rightMenu;
private int floatW;
private int floatH;
private float downRawX;
private float downRawY;
private float menuW;
public MyFloatView(@NonNull Context context,boolean isShowFloatBar) {
super(context);
this.isShowFloatBar = isShowFloatBar;
getScreenInfo(context);
createContentView(context);
createWindowManager(context);
setOrientation(LinearLayout.HORIZONTAL);
}
/**
* 创建悬浮窗
* @param context
*/
private void createContentView(Context context) {
ImageView floatView = new ImageView(context);
floatView.setImageResource(android.R.drawable.ic_menu_add);
addView(floatView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
measureChild(floatView,MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED);
floatW = floatView.getMeasuredWidth();
floatH = floatView.getMeasuredHeight();
if (isShowFloatBar){
createFloatBarView(context);
}
}
/**
* 创建悬浮条
* @param context
*/
private void createFloatBarView(Context context){
leftMenu = (LinearLayout) View.inflate(context,R.layout.layout_left_menu,null);
rightMenu = (LinearLayout) View.inflate(context,R.layout.layout_right_menu,null);
leftMenu.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED);
menuW = leftMenu.getMeasuredWidth();
leftMenu.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dismissMenu();
}
});
rightMenu.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dismissMenu();
}
});
}
/**
* 初始化windowmanager,我们用它来加载悬浮窗
* @param context
*/
private void createWindowManager(Context context) {
wm = (WindowManager) context.getSystemService(Service.WINDOW_SERVICE);
floatParams = new WindowManager.LayoutParams();
floatParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
floatParams.height = floatH;
floatParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
floatParams.gravity = Gravity.LEFT | Gravity.TOP;
floatParams.x = 0;
floatParams.y = screenH / 2;
floatParams.format = PixelFormat.RGBA_8888;
}
/**
* 获取屏幕宽高信息
* @param context
*/
private void getScreenInfo(Context context){
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
screenW = displayMetrics.widthPixels;
screenH = displayMetrics.heightPixels;
}
/**
* 悬浮条是否展示当中
* @return
*/
private boolean isMenuDisplay(){
return getChildCount() > 1;
}
/**
* 此时悬浮窗的位置是否在左边
* @return
*/
private boolean isFloatSlideLeft(){
return floatParams.x + floatW /2 <= screenW /2;
}
/**
* 展示悬浮条
*/
private void showMenu() {
if (isFloatSlideLeft()){
addView(rightMenu,1);
}else{
addView(leftMenu,0);
floatParams.x = (int) (floatParams.x - menuW);
wm.updateViewLayout(MyFloatView.this,floatParams);
}
}
/**
* 隐藏悬浮条
*/
private void dismissMenu() {
if (isFloatSlideLeft()){
removeView(rightMenu);
}else{
floatParams.x = (int) (floatParams.x + menuW);
wm.updateViewLayout(this,floatParams);
removeView(leftMenu);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
downRawX = event.getRawX();
downRawY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
if (!isMenuDisplay()){
float rawX = event.getRawX();
float rawY = event.getRawY();
floatParams.x = (int) (rawX - downX);
floatParams.y = (int) (rawY - downY);
wm.updateViewLayout(this,floatParams);//通过手指拖动改变悬浮球的位置
}
break;
case MotionEvent.ACTION_UP:
float upRawX = event.getRawX();
float upRawY = event.getRawY();
float absX = Math.abs(upRawX - downRawX);
float absY = Math.abs(upRawY - downRawY);
if (isShowFloatBar && (absX < 0.2f || absY < 0.2f)){//单机悬浮球
if (isMenuDisplay()){
dismissMenu();
}else{
showMenu();
}
}else{
if (!isShowFloatBar || !isMenuDisplay()){//悬浮球自动靠边
floatParams.x = isFloatSlideLeft() ? 0 : screenW - floatW;
if (upRawY < floatH) floatParams.y = 0;
if (upRawY > screenH - floatH) floatParams.y = screenH - floatH;
wm.updateViewLayout(this,floatParams);
}
}
break;
}
return super.onTouchEvent(event);
}
public void show(){
if (!isFloatShow){
isFloatShow = true;
floatParams.x = 0;
floatParams.y = screenH / 2;
wm.addView(this,floatParams);
}
}
public void dismiss(){
if (isFloatShow){
if (isMenuDisplay()){
if (isFloatSlideLeft()){
removeView(rightMenu);
}else{
removeView(leftMenu);
}
}
isFloatShow = false;
wm.removeView(this);
}
}
}

浙公网安备 33010602011771号