Androidカスタムログインダイアログボックスの基本クラスのカプセル化、およびソフトキーボードのポップアップで自動的に位置を移動します

ダイアログボックスなどの一般的に使用されるコンポーネントは、一度使用するとパッケージ化するのが最適です。もう一度使うととても簡単です。取って再利用するだけです。

仕事で使用する管理者ログインボックスは以下のとおりです。デュアルスクリーン表示のため、背面画面に表示されるダイアログボックスではシステムソフトキーボードを呼び出せないので、自分でシステムソフトウェアディスクを実現しました。

ただし、ソフトキーボードがポップアップしたら、ダイアログボックスを停止する必要があります。これはどのように壊れますか?方法があります。これは、ソフトキーボードがポップアップすると自動的に位置を移動するダイアログボックスです。

まず、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);
    }

 

おすすめ

転載: blog.csdn.net/qq8864/article/details/110160784