I originally wanted to implement a button suspended on other controls through framelayout, but I felt it was very troublesome and needed to dynamically fill each interface. So when I thought of the floating window, I customized an ImageView to display the global button.
1. First of all, because of the floating window type, you need to add permissions. For SDK>=23, you need to obtain permissions dynamically. I use 22 here.
<uses-permission android:name=".SYSTEM_ALERT_WINDOW" /> <uses-permission android:name=".WRITE_SETTINGS"/>
2. Obtain the global WindowManager params data through application
private wmParams=new (); public getMywmParams(){ return wmParams; }
3. Customize the ImageView and realize the status selection of clicks. A callback interface is written for processing click events.
public class CustomeMovebutton extends ImageView { private final int statusHeight; int sW; int sH; private float mTouchStartX; private float mTouchStartY; private float x; private float y; private boolean isMove=false; private Context context; private WindowManager wm = (WindowManager) getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE); private wmParams = ((MyApplication) getContext().getApplicationContext()).getMywmParams(); private float mLastX; private float mLastY; private float mStartX; private float mStartY; private long mDownTime; private long mUpTime; private OnSpeakListener listener; public CustomeMovebutton(Context context) { this(context,null); = context; } public CustomeMovebutton(Context context, AttributeSet attrs) { this(context, attrs,-1); } public CustomeMovebutton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs,defStyleAttr); sW = ().getWidth(); sH = ().getHeight(); statusHeight = getStatusHeight(context); } /** * The height of the status bar * */ public static int getStatusHeight(Context context) { int statusHeight = -1; try { Class clazz = ("$dimen"); //Use reflection to get instance Object object = (); int height = (("status_bar_height") .get(object).toString()); statusHeight = ().getDimensionPixelSize(height); } catch (Exception e) { (); } return statusHeight; } @Override public boolean onTouchEvent(MotionEvent event) { //Get the coordinates of the relative screen, that is, use the upper left corner of the screen as the origin point x = (); y = () - statusHeight; //statusHeight is the height of the system status bar switch (()) { case MotionEvent.ACTION_DOWN: //Press setImageResource(.btn_voice_pressed); mTouchStartX = (); mTouchStartY = (); mStartX = (); mStartY = (); mDownTime = (); isMove = false; break; case MotionEvent.ACTION_MOVE: //Finger movement updateViewPosition(); isMove = true; break; case MotionEvent.ACTION_UP: //Release your hand setImageResource(.btn_voice_rest); mLastX = (); mLastY = (); mUpTime = (); //The time it takes to press to lift is greater than 500 milliseconds, and the absolute value of lift is greater than 20 pixels to handle click event if(mUpTime - mDownTime < 500){ if((mStartX- mLastX )< 20.0 && (mStartY - mLastY) < 20.0){ if (listener!=null){ (); } } } break; } return true; } private void updateViewPosition() { = (int) (x - mTouchStartX); = (int) (y- mTouchStartY); (this, wmParams); //Refresh the display } /** * Set the click callback interface */ public interface OnSpeakListener{ void onSpeakListener(); } public void setOnSpeakListener(OnSpeakListener listener){ =listener; } }
4. Used in Activity, which includes setting the parameters and position parameters of the picture
public class MainActivity extends AppCompatActivity{ private WindowManager wm; private wmParams; private CustomeMovebutton CustomeMovebutton; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = getResources().getDisplayMetrics(); int widthPixels = ; int heightPixels = ; wmParams = ((MyApplication) getApplication()).getMywmParams(); = .TYPE_SYSTEM_ALERT; = PixelFormat.RGBA_8888;//Set background pictures = .FLAG_NOT_TOUCH_MODAL | .FLAG_NOT_FOCUSABLE ;// = |;// = widthPixels-150; //Set position pixel = heightPixels-110; =200; //Set the image size =200; CustomeMovebutton = new CustomeMovebutton(getApplicationContext()); (.btn_voice_rest); (CustomeMovebutton, wmParams); (new () { @Override public void onSpeakListener() { (, "Click Event", Toast.LENGTH_SHORT).show(); } }); } @Override protected void onDestroy() { (); if(CustomeMovebutton != null){ (CustomeMovebutton); } } }
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.