显示弹出视图的一般想法是使用WindowManager 创建它们,它不受PopupWindow 的限制。
我假设InputMethodService 负责显示弹出视图。
由于显示此类窗口需要在 API 23 及更高版本中获得覆盖权限,因此我们需要创建一个临时 Activity 来为我们执行此操作。获得许可的结果将使用EventBus 事件传递给InputMethodService。您可以根据架构检查您想要的覆盖权限(例如每次键盘上升时)。
这是这个想法的一个实现,它可能需要一些操作才能完全按照您的意愿工作。希望对你有帮助。
MyInputMethodService.java
import android.content.Intent;
import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.provider.Settings;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class MyInputMethodService extends InputMethodService {
private FloatViewManager mFloatViewManager;
@Override
public void onCreate() {
super.onCreate();
EventBus.getDefault().register(this);
checkDrawOverlayPermission();
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
private boolean checkDrawOverlayPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
Intent intent = new Intent(this, CheckPermissionActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
return false;
} else {
return true;
}
}
private void showPopup(Key key, int xPosition){
mFloatViewManager = new FloatViewManager(this);
if (checkDrawOverlayPermission()) {
mFloatViewManager.showFloatView(key, xPosition);
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(CanDrawOverlaysEvent event) {
if (event.isAllowed()) {
mFloatViewManager.showFloatView(key, xPosition);
} else {
// Maybe show an error
}
}
}
FloatViewManager.java
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import static android.content.Context.WINDOW_SERVICE;
public class FloatViewManager {
private WindowManager mWindowManager;
private View mFloatView;
private WindowManager.LayoutParams mFloatViewLayoutParams;
@SuppressLint("InflateParams")
public FloatViewManager(Context context) {
mWindowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE);
LayoutInflater inflater = LayoutInflater.from(context);
mFloatView = inflater.inflate(R.layout.float_view_layout, null);
// --------- do initializations:
TextView textView = mFloatView.findViewById(R.id.textView);
// ...
// ---------
mFloatViewLayoutParams = new WindowManager.LayoutParams();
mFloatViewLayoutParams.format = PixelFormat.TRANSLUCENT;
mFloatViewLayoutParams.flags = WindowManager.LayoutParams.FORMAT_CHANGED;
mFloatViewLayoutParams.type = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
: WindowManager.LayoutParams.TYPE_PHONE;
mFloatViewLayoutParams.gravity = Gravity.NO_GRAVITY;
mFloatViewLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mFloatViewLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
}
public void dismissFloatView() {
mWindowManager.removeViewImmediate(mFloatView);
}
public void showFloatView(Key key, int xPosition) {
// calculate x and y position as you did instead of 0
mFloatViewLayoutParams.x = 0;
mFloatViewLayoutParams.y = 0;
mWindowManager.addView(mFloatView, mFloatViewLayoutParams);
mWindowManager.updateViewLayout(mFloatView, mFloatViewLayoutParams);
}
}
CheckPermissionActivity.java
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import org.greenrobot.eventbus.EventBus;
public class CheckPermissionActivity extends AppCompatActivity {
private static final int REQUEST_CODE_DRAW_OVERLAY_PERMISSION = 5;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_DRAW_OVERLAY_PERMISSION);
} else {
finish();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_DRAW_OVERLAY_PERMISSION) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Settings.canDrawOverlays(this)) {
EventBus.getDefault().post(new CanDrawOverlaysEvent(true));
} else {
EventBus.getDefault().post(new CanDrawOverlaysEvent(false));
}
finish();
}
}
}
CanDrawOverlaysEvent.java
public class CanDrawOverlaysEvent {
private boolean mIsAllowed;
public CanDrawOverlaysEvent(boolean isAllowed) {
mIsAllowed = isAllowed;
}
public boolean isAllowed() {
return mIsAllowed;
}
}
build.gradle
dependencies {
implementation 'org.greenrobot:eventbus:3.1.1'
}