android 自定义登陆对话框基类封装,且随着软键盘的弹起自动移动位置

2020-12-01 10:35:12 浏览数 (1)

像对话框这种常用的组件,用过一次最好做个封装。再次用到时就很简单啦。直接拿过来复用即可。

以下是工作中用到的管理员登录框,由于是双屏异显,在后屏弹出的对话框,没法调用系统软键盘,于是自己实现了个系统软件盘。

但一弹出来软键盘,对话框就被该住了!这怎么破?方法是有的。就是本文介绍的,随着软键盘的弹起自动移动位置的对话框。

先封装实现个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);
    }

0 人点赞