Android 任何位置的可移动悬浮窗
刚好要做这块的东西,所以网上翻了下资料,百度出来的基本上都是:默认起始位置左上角,还不能改动,一改动起始位置,第二次拖动就不正常了~~
下面直接附上任意位置可拖动的源码(由于是demo写的比较乱):
package com.example.dengshaomin.repluginhost; import android.content.Context; import android.graphics.PixelFormat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private WindowManager wm = null; private WindowManager.LayoutParams wmParams = null; private ImageView leftbtn = null; private int statusBarHeight1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { //根据资源ID获取响应的尺寸值 statusBarHeight1 = getResources().getDimensionPixelSize(resourceId); } setContentView(R.layout.activity_main); initFloatView(); } public void textClick(View view) { Toast.makeText(MainActivity.this, view.getId() + "", Toast.LENGTH_SHORT).show(); } private void initFloatView() { //应用内悬浮窗,ondestory时记得销毁悬浮窗 /* wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); // //设置LayoutParams(全局变量)相关参数 wmParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT); */ ///全局悬浮按钮,会显示在其他应用和桌面上 //获取WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); //设置LayoutParams(全局变量)相关参数 wmParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_TOAST, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT); wmParams.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; //以屏幕左上角为原点,设置x、y初始值 wmParams.x = 0; wmParams.y = 0; //设置悬浮窗口长宽数据 wmParams.width = 200; wmParams.height = 200; createLeftFloatView(); leftbtn.invalidate(); } private void createLeftFloatView() { leftbtn = new ImageView(this); leftbtn.setImageResource(R.mipmap.ic_launcher); leftbtn.setAlpha(100); leftbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Toast.makeText(MainActivity.this,"click",Toast.LENGTH_SHORT).show(); } }); //调整悬浮窗口 //显示myFloatView图像 wm.addView(leftbtn, wmParams); leftbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "float", Toast.LENGTH_SHORT).show(); } }); leftbtn.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (wm != null) { wm.removeViewImmediate(leftbtn); } // Toast.makeText(MainActivity.this, "finish", Toast.LENGTH_SHORT).show(); return true; } }); leftbtn.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // 当前值以屏幕左上角为原点 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mStartX = event.getRawX(); mStartY = event.getRawY(); break; case MotionEvent.ACTION_MOVE: wmParams.x += event.getRawX() - mStartX; wmParams.y += event.getRawY() - mStartY; wm.updateViewLayout(leftbtn, wmParams); mStartX = event.getRawX(); mStartY = event.getRawY(); break; case MotionEvent.ACTION_UP: break; } // 消耗触摸事件 return true; } }); } private float mStartX, mStartY; }
项目地址: http://ol58b2pn9.bkt.clouddn.com/+%E5%AF%B9%E8%AF%9D%E6%A1%86%E6%82%AC%E6%B5%AE%E7%AA%97.zip
以上代码,只有显示及拖动悬浮框的处理,更高阶的悬浮框可以参考一下链接:
转载标明出处:http://www.cnblogs.com/no-coding
有问题邮件 nocoding@163.com QQ:418244382