像对话框这种常用的组件,用过一次最好做个封装。再次用到时就很简单啦。直接拿过来复用即可。
以下是工作中用到的管理员登录框,由于是双屏异显,在后屏弹出的对话框,没法调用系统软键盘,于是自己实现了个系统软件盘。
但一弹出来软键盘,对话框就被该住了!这怎么破?方法是有的。就是本文介绍的,随着软键盘的弹起自动移动位置的对话框。
先封装实现个baseDialog基础类,把通用的操作封装一下。
代码语言:javascript复制package com.newcapec.visitorsystem.dialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
/**
* Created by yangyongzhen on 2017/5/12.
*/
public abstract class BaseDialog<T> extends Dialog implements DialogInterface.OnDismissListener, DialogInterface.OnShowListener{
protected View rootView;
protected boolean isInit;
protected Context context;
protected boolean isFullScreen;
protected Window window;
public BaseDialog(Context context) {
super(context);
this.context = context;
window = getWindow();
}
public BaseDialog(Context context, boolean isFullScreen) {
super(context);
this.context = context;
this.isFullScreen = isFullScreen;
window = getWindow();
}
public BaseDialog(Context context, int themeResId) {
super(context, themeResId);
this.context = context;
window = getWindow();
// sysApplication = (App) ((Activity)context).getApplication();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//hideBottomUIMenu();
// showBottomUIMenu();
rootView = getBindingRoot();
if(rootView!=null){
setContentView(rootView);
}else{
setContentView(getLayoutResid());
}
initView();
initData();
initEvent();
setOnDismissListener(this);
setOnShowListener(this);
}
protected int getHeight() {
return 0;
}
protected int getWidth() {
return 0;
}
abstract View getBindingRoot();
protected void initView() {
//window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); //清除灰色背景
}
protected int getLayoutResid() {
return 0;
}
protected void initData() {
}
protected void initEvent() {
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
//hideBottomUIMenu();
Log.i("Dialog", "onDetachedFromWindow");
}
@Override
public void cancel() {
super.cancel();
}
@Override
public void onDismiss(DialogInterface dialog) {
doDismiss();
}
public void doDismiss() {}
/**
* 隐藏虚拟按键:必须放到setContentView前面
*/
protected void hideBottomUIMenu() {
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) {
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
protected void showBottomUIMenu() {
//隐藏虚拟按键,并且全屏
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.VISIBLE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView =this.getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
@Override
public void onShow(DialogInterface dialog) {
if(!isInit) {
isInit = true;
}
}
@Override
public void show() {
//focusNotAle(window);
super.show();
//hideNavigationBar(window);
//clearFocusNotAle(window);
}
}
/**
* 后屏显示的Dialog的基础类,因为后屏的Dialog的像素密度跟前屏不一样,所以需要改下像素密度才能正常显示
* 前屏像素密度为1,后屏获取到的为2
*/
public class BackDialog extends BaseDialog {
private final String TAG = "BackDialog";
public BackDialog(Context context, int themeResId){
super(context, themeResId);
float scale = context.getResources().getDisplayMetrics().density;
int dp =(int) (48 / scale 0.5f);
Log.e(TAG,"dp:" dp);
}
@Override
View getBindingRoot() {
//更改Dialog的像素密度
Utils.setDensity(App.getContext(),context);
//使背景变暗
// WindowManager.LayoutParams lp = getWindow().getAttributes();
// lp.alpha = 0.6f;
// getWindow().setAttributes(lp);
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
return null;
}
/**
* 禁掉系统软键盘
*/
public void hideSoftInputMethod(EditText edit) {
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
int currentVersion = android.os.Build.VERSION.SDK_INT;
String methodName = null;
if (currentVersion >= 16) {
// 4.2
methodName = "setShowSoftInputOnFocus";
} else if (currentVersion >= 14) {
// 4.0
methodName = "setSoftInputShownOnFocus";
}
if (methodName == null) {
edit.setInputType(InputType.TYPE_NULL);
} else {
Class<EditText> cls = EditText.class;
Method setShowSoftInputOnFocus;
try {
setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class);
setShowSoftInputOnFocus.setAccessible(true);
setShowSoftInputOnFocus.invoke(edit, false);
} catch (NoSuchMethodException e) {
edit.setInputType(InputType.TYPE_NULL);
e.printStackTrace();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
以下是我的LoginDlg继承自基类:
代码语言:javascript复制package com.newcapec.visitorsystem.dialog;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.InputType;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import com.newcapec.visitorsystem.R;
import com.newcapec.visitorsystem.diyview.AbcNumberViewBack;
import com.newcapec.visitorsystem.utils.Utils;
public class LoginDlg extends BackDialog {
private final String TAG = "LoginDlg";
EditText editInputUsername,editInputPassword;
AbcNumberViewBack abcNumberView;
Button btnLogin;
private OnLoginListener onLoginListener;
//private DialogLoginBinding loginBinding;
public LoginDlg(Context context, int themeResId, AbcNumberViewBack abcNumberViewBack){
super(context, themeResId);
abcNumberView = abcNumberViewBack;
}
@Override
View getBindingRoot() {
super.getBindingRoot();
rootView = LayoutInflater.from(context).inflate(R.layout.dialog_login, null, false);
//loginBinding = DataBindingUtil.inflate(LayoutInflater.from(context),R.layout.dialog_login,null,false);
return rootView;
}
@Override
protected void initView() {
super.initView();
final Window dialogWindow = this.getWindow();
WindowManager.LayoutParams lp1 = dialogWindow.getAttributes();
lp1.width = Utils.dp2px(910); //设置宽度
lp1.height = Utils.dp2px(660); //设置高度
//lp1.width = width;
//lp1.height = height;
dialogWindow.setAttributes(lp1);
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); //清除灰色背景
editInputUsername = findViewById(R.id.edit_login_username);
editInputPassword = findViewById(R.id.edit_login_password);
btnLogin = findViewById(R.id.btn_login);
}
@Override
protected void initData() {
super.initData();
initTouch();
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG,"btn login click:");
abcNumberView.hideKeyboard();
resetPosition(0,0,Gravity.CENTER);
if(onLoginListener != null){
onLoginListener.onClickLogin(editInputUsername.getText().toString(),editInputPassword.getText().toString());
}
//dismiss();
}
});
//KeyBoardUtils.openKeybord(editInputUsername,context);
}
/**
* 重新设置Dialog的显示位置
*/
protected void resetPosition(int x,int y,int gravity){
Window mWindow = getWindow();
mWindow .setGravity(gravity);
WindowManager.LayoutParams lp = mWindow.getAttributes();
lp.x = x; // 新位置X坐标
lp.y = y; // 新位置Y坐标
onWindowAttributesChanged(lp);
}
@Override public void show(){
super.show();
}
@Override public void dismiss(){
editInputUsername.setText("");
editInputPassword.setText("");
super.dismiss();
}
@SuppressLint("ClickableViewAccessibility")
private void initTouch() {
//初始化键盘监听
hideSoftInputMethod(editInputUsername);
editInputUsername.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
Log.e(TAG, "键盘--------" event.getAction());
abcNumberView.setmEdit(editInputUsername);
if (event.getAction() == MotionEvent.ACTION_UP) {
if (view != null) {
resetPosition(0,0,Gravity.TOP);
if (!abcNumberView.isShow()) {
abcNumberView.showKeyboard();
}
}
}
return false;
}
});
hideSoftInputMethod(editInputPassword);
editInputPassword.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
Log.e(TAG, "键盘--------" event.getAction());
abcNumberView.setmEdit(editInputPassword);
if (event.getAction() == MotionEvent.ACTION_UP) {
if (view != null) {
resetPosition(0,0,Gravity.TOP);
if (!abcNumberView.isShow()) {
abcNumberView.showKeyboard();
}
}
}
return false;
}
});
abcNumberView.setOkListener(new AbcNumberViewBack.OnOkListener() {
@Override
public void onOk(String e) {
resetPosition(0,0,Gravity.CENTER);
}
});
}
public interface OnLoginListener {
void onClickLogin(String name,String pwd);//点击了确认
}
public void setOnLoginListener(OnLoginListener onLoginListener) {
this.onLoginListener = onLoginListener;
}
}
自动移动位置的秘诀:
代码语言:javascript复制 /**
* 重新设置Dialog的显示位置
*/
protected void resetPosition(int x,int y,int gravity){
Window mWindow = getWindow();
mWindow .setGravity(gravity);
WindowManager.LayoutParams lp = mWindow.getAttributes();
lp.x = x; // 新位置X坐标
lp.y = y; // 新位置Y坐标
onWindowAttributesChanged(lp);
}