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.