前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >android 自定义登陆对话框基类封装,且随着软键盘的弹起自动移动位置

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

作者头像
杨永贞
发布2020-12-01 10:35:12
6790
发布2020-12-01 10:35:12
举报

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

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

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

先封装实现个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);
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档