Christmas write a program to practice hand Android full interface suspension button to achieve

  • 2020-12-07 04:26:33
  • OfStack

At first, I thought that the floating window could be implemented by PopupWindow in Android. Although it has been implemented, its limitations are very great. For example, PopupWindow must have a carrier View, that is, it must be specified on top of that View to be implemented. Display PopupWindow with the View as the relative position. This limits its intelligence to the relative display on the user interaction window. While unable to freely drag the position and display on the desktop.

So I looked up some data, there are two ways to achieve. The first is custom Toast, which runs on all interfaces, meaning that no interface can override it. The other is the CompatModeWrapper class from Android. ConmpatModeWrapper is the base class and its inner class WindowManagerImpl does most of its work. This object can be obtained by getApplication().getSystemService (Context.WINDOW_SERVICE). (Note: if obtained through ES21en.getSystemService (Context.WINDOW_SERVICE), only LocalWindowManager belongs to Activity).

After a brief introduction, let's look directly at the code implementation, with comments already written in the code.


MainActivity.java
package com.example.floatviewdemo;
import com.example.floatviewdemo.service.FloatViewService;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
  @Override
 protected void onStart() {
  Intent intent = new Intent(MainActivity.this, FloatViewService.class); 
     // Start the FloatViewService 
     startService(intent); 
 super.onStart();
 }
 
 @Override
 protected void onStop() {
 //  Destroy suspension window 
 Intent intent = new Intent(MainActivity.this, FloatViewService.class); 
    // Termination of FloatViewService 
    stopService(intent); 
    super.onStop();
 }
}

activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#fff"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context="com.example.floatviewdemo.MainActivity" >
  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />
</RelativeLayout>

service class for levitating Windows


package com.example.floatviewdemo.service;
import com.example.floatviewdemo.R;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;
public class FloatViewService extends Service  
{ 
 private static final String TAG = "FloatViewService"; 
  // Define the floating window layout  
  private LinearLayout mFloatLayout; 
  private WindowManager.LayoutParams wmParams; 
  // Creates an object that floats the window to set layout parameters  
  private WindowManager mWindowManager; 
  private ImageButton mFloatView; 
  @Override 
  public void onCreate()  
  { 
    super.onCreate(); 
    Log.i(TAG, "onCreate"); 
    createFloatView();    
  } 
  @SuppressWarnings("static-access")
 @SuppressLint("InflateParams") private void createFloatView() 
  { 
    wmParams = new WindowManager.LayoutParams(); 
    // through getApplication Access is WindowManagerImpl.CompatModeWrapper 
    mWindowManager = (WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE); 
    // Set up the window type 
    wmParams.type = LayoutParams.TYPE_PHONE;  
    // Format the image so that the background is transparent  
    wmParams.format = PixelFormat.RGBA_8888;  
    // Set the floating window to be unfocused (implement operations on visible Windows other than the floating window)  
    wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE;    
    // Adjust the parking position shown in the suspension window to the left top  
    wmParams.gravity = Gravity.LEFT | Gravity.TOP;     
    //  Set with the top left corner of the screen as the origin x , y Initial value, relative to gravity 
    wmParams.x = 0; 
    wmParams.y = 152; 
    // Set the length and width of the floating window   
    wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; 
    wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; 
    LayoutInflater inflater = LayoutInflater.from(getApplication()); 
    // Gets the layout where the floating window view is located  
    mFloatLayout = (LinearLayout) inflater.inflate(R.layout.alert_window_menu, null); 
    // add mFloatLayout 
    mWindowManager.addView(mFloatLayout, wmParams); 
    // Floating window button  
    mFloatView = (ImageButton) mFloatLayout.findViewById(R.id.alert_window_imagebtn);
    mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0, 
        View.MeasureSpec.UNSPECIFIED), View.MeasureSpec 
        .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 
    // Set to listen for touch movements in the floating window  
    mFloatView.setOnTouchListener(new OnTouchListener()  
    { 
     boolean isClick;
  @SuppressLint("ClickableViewAccessibility") @Override
  public boolean onTouch(View v, MotionEvent event) {
  switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
   mFloatView.setBackgroundResource(R.drawable.circle_red);
   isClick = false;
   break;
  case MotionEvent.ACTION_MOVE:
   isClick = true;
   // getRawX Is the coordinates of the touch position relative to the screen, getX Is the coordinates relative to the button 
   wmParams.x = (int) event.getRawX()
    - mFloatView.getMeasuredWidth() / 2;
   //  Reduction of 25 Is the height of the status bar 
   wmParams.y = (int) event.getRawY()
    - mFloatView.getMeasuredHeight() / 2 - 75;
   //  The refresh 
   mWindowManager.updateViewLayout(mFloatLayout, wmParams);
   return true;
  case MotionEvent.ACTION_UP:
   mFloatView.setBackgroundResource(R.drawable.circle_cyan);
   return isClick;//  Return here false Is a move event and returns true Then release the event and you can start by clicking No. 
  default:
   break;
  }
  return false;
  }
    });  
    mFloatView.setOnClickListener(new OnClickListener()  
    { 
      @Override 
      public void onClick(View v)  
      { 
        Toast.makeText(FloatViewService.this, "1 Not a hundred bucks! ", Toast.LENGTH_SHORT).show(); 
      } 
    }); 
  } 
  @Override 
  public void onDestroy()  
  { 
    super.onDestroy(); 
    if(mFloatLayout != null) 
    { 
      // Remove the suspension window  
      mWindowManager.removeView(mFloatLayout); 
    } 
  }
 @Override
 public IBinder onBind(Intent intent) {
 return null;
 } 
}

xml file for floating window


alert_window_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="wrap_content"
  android:orientation="vertical" >
  <ImageButton
    android:id="@+id/alert_window_imagebtn" 
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@drawable/float_window_menu"
    android:contentDescription="@null"
    />
</LinearLayout>

The above content is the realization of Android full interface suspension button all the description, I hope you like.


Related articles: