Android桌面悬浮窗效果怎么实现

2025-12-18 04:02:37
推荐回答(1个)
回答1:

  可以根据项目需要改变其相应布局。
  package com.zk.me;
  import java.util.List;
  import android.app.Activity;
  import android.content.ComponentName;
  import android.content.Context;
  import android.content.Intent;
  import android.content.pm.PackageInfo;
  import android.content.pm.PackageManager;
  import android.content.pm.PackageManager.NameNotFoundException;
  import android.content.pm.ResolveInfo;
  import android.os.Bundle;
  import android.view.Gravity;
  import android.view.Menu;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.view.Window;
  import android.view.WindowManager;
  import android.widget.ImageView;
  import android.widget.Toast;
  public class MainActivity extends Activity implements OnClickListener {
  private WindowManager windowManager = null;
  private WindowManager.LayoutParams windowManagerParams = null;
  private MyFloatView floatView = null;
  @Override
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  requestWindowFeature(Window.FEATURE_NO_TITLE);// 取消标题栏
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  WindowManager.LayoutParams.FLAG_FULLSCREEN);// 全屏
  setContentView(R.layout.activity_main);
  createView();
  }
  public void onDestroy() {
  super.onDestroy();
  // 在程序退出(Activity销毁)时销毁悬浮窗口
  }
  private void createView() {
  floatView = new MyFloatView(getApplicationContext());
  floatView.setOnClickListener(this);
  ImageView view = new ImageView(this);
  view.setImageResource(R.drawable.ic_launcher);
  floatView.addView(view); // 这里简单的用自带的icon来做演示
  windowManager = (WindowManager) getApplicationContext()
  .getSystemService("window");
  // 设置LayoutParams(全局变量)相关参数
  windowManagerParams = ((FloatApplication) getApplication())
  .getWindowParams();
  windowManagerParams.type = 2003; // 设置window type
  // windowManagerParams.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明
  // 设置Window flag
  windowManagerParams.flags = 40;
  windowManagerParams.format = 1;
  // 调整悬浮窗口至左上角,便于调整坐标
  windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP;
  // 以屏幕左上角为原点,设置x、y初始值
  windowManagerParams.x = 0;
  windowManagerParams.y = 0;
  // 设置悬浮窗口长宽数据
  windowManagerParams.width = 40;
  windowManagerParams.height = 40;
  // 显示myFloatView图像
  windowManager.addView(floatView, windowManagerParams);
  }
  public void onClick(View v) {
  Toast.makeText(this, "Clicked", Toast.LENGTH_SHORT).show();
  openCLD("com.jovian.android.pqgl", getApplicationContext());
  }
  public static void openCLD(String packageName, Context context) {// 打开移动警务应用
  PackageManager packageManager = context.getPackageManager();
  PackageInfo pi = null;
  try {
  pi = packageManager.getPackageInfo(packageName, 0);
  } catch (NameNotFoundException e) {
  }
  Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
  resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
  resolveIntent.setPackage(packageName);
  List apps = packageManager.queryIntentActivities(
  resolveIntent, 0);
  ResolveInfo resolveinfo = apps.iterator().next();
  if (resolveinfo != null) {
  String className = resolveinfo.activityInfo.name;
  Intent intent = new Intent(Intent.ACTION_MAIN);
  intent.addCategory(Intent.CATEGORY_LAUNCHER);
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  ComponentName cn = new ComponentName(packageName, className);
  intent.setComponent(cn);
  context.startActivity(intent);
  }
  }
  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onRestoreInstanceState(savedInstanceState);
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
  }
  }
  package com.zk.me;
  import android.content.Context;
  import android.graphics.Rect;
  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.LinearLayout;
  public class MyFloatView extends LinearLayout {
  private float mTouchX;
  private float mTouchY;
  private float x;
  private float y;
  private float mStartX;
  private float mStartY;
  private OnClickListener mClickListener;
  private WindowManager windowManager = (WindowManager) getContext()
  .getApplicationContext().getSystemService("window");
  // 此windowManagerParams变量为获取的全局变量,用以保存悬浮窗口的属性
  private WindowManager.LayoutParams windowManagerParams = ((FloatApplication) getContext()
  .getApplicationContext()).getWindowParams();
  public MyFloatView(Context context) {
  super(context);
  }
  @Override
  public boolean onTouchEvent(MotionEvent event) {
  // 获取到状态栏的高度
  Rect frame = new Rect();
  getWindowVisibleDisplayFrame(frame);
  int statusBarHeight = frame.top;
  System.out.println("statusBarHeight:" + statusBarHeight);
  // 获取相对屏幕的坐标,即以屏幕左上角为原点
  x = event.getRawX();
  y = event.getRawY() - statusBarHeight; // statusBarHeight是系统状态栏的高度
  Log.i("tag", "currX" + x + "====currY" + y);
  switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN: // 捕获手指触摸按下动作
  // 获取相对View的坐标,即以此View左上角为原点
  mTouchX = event.getX();
  mTouchY = event.getY();
  mStartX = x;
  mStartY = y;
  Log.i("tag", "startX" + mTouchX + "====startY" + mTouchY);
  break;
  case MotionEvent.ACTION_MOVE: // 捕获手指触摸移动动作
  updateViewPosition();
  break;
  case MotionEvent.ACTION_UP: // 捕获手指触摸离开动作
  updateViewPosition();
  mTouchX = mTouchY = 0;
  if ((x - mStartX) < 5 && (y - mStartY) < 5) {
  if (mClickListener != null) {
  mClickListener.onClick(this);
  }
  }
  break;
  }
  return true;
  }
  @Override
  public void setOnClickListener(OnClickListener l) {
  this.mClickListener = l;
  }
  private void updateViewPosition() {
  // 更新浮动窗口位置参数
  windowManagerParams.x = (int) (x - mTouchX);
  windowManagerParams.y = (int) (y - mTouchY);
  windowManager.updateViewLayout(this, windowManagerParams); // 刷新显示
  }
  }