像对话框这种常用的组件,用过一次最好做个封装。再次用到时就很简单啦。直接拿过来复用即可。
以下是工作中用到的管理员登录框,由于是双屏异显,在后屏弹出的对话框,没法调用系统软键盘,于是自己实现了个系统软件盘。
但一弹出来软键盘,对话框就被该住了!这怎么破?方法是有的。就是本文介绍的,随着软键盘的弹起自动移动位置的对话框。
先封装实现个baseDialog基础类,把通用的操作封装一下。
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继承自基类:
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; } }
自动移动位置的秘诀:
/** * 重新设置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); }