Androidは入力ボックス付きソフトキーボードをカスタマイズし、ソーシャルソフトウェアのコメント返信機能を実現


最近、ソーシャルソフトウェアのコメント機能を備えたアプリを作りましたが、今日の週末にまとめました.自分が忘れたり、記憶を増やしたりすることを防ぐために、他の人に助けてほしいと思っています.
ソーシャルソフトウェアのコメント機能をして、私が出会った難点はコメント機能uiを書くことではありません.最大の問題はコメントをクリックして返信ボックスのあるソフトキーボードインタフェースをポップアップすることです.そして、ソフトキーボードと入力ボックスは同時に表示され、以下のように表示されます.
このコメントに返信する弾枠はdialog+ポップアップソフトキーボードの組み合わせを利用しており、主な実現コードは以下の通りである.
package com.example.editcomment;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public abstract class AboveInputMethodDialog extends Dialog {

    private int[] decorViewOutLocation = new int[2];
    private InputMethodManager inputMethodManager;

    //      
    private int dialogMinOffset;

    public AboveInputMethodDialog(Context context) {
        super(context, R.style.transparentBackgroundDiaolg);

        setContentView(getContextViewResource());

        updateWindow();

        setCancelable(true);
        setCanceledOnTouchOutside(false);

        inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

        //    
        getEditText().requestFocus();
        //            
        KeyboardChangeListener keyboardChangeListener=new KeyboardChangeListener(context);
        keyboardChangeListener.setKeyBoardListener(new KeyboardChangeListener.KeyBoardListener() {
            @Override
            public void onKeyboardChange(boolean isShow, int keyboardHeight) {

               if (isShow){
                   dismiss();
               }
            }
        });

        //       ,  send     
        getEditText().addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length()>0){
                    getText().setTextColor(Color.parseColor("#000000"));
                }else {
                    getText().setTextColor(Color.parseColor("#f4f4f4"));
                }

            }
        });
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        //clearInputMethodStatusListener();
        if (hasFocus && getWindow() == null) {
            //           
           // hideInputMethod(getEditText());
        } else {
            //           
            View decorView = getWindow().getDecorView();
            decorView.postDelayed(() -> {
                showInputMethod(getEditText());
            }, 100L);
        }
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        //      
        if (isOutOfBounds(getContext(), event)) {
            dismiss();
            return true;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void dismiss() {
        //               ,              。
        //          ,         ,           。
        hideInputMethod(getEditText());
        super.dismiss();
    }

    //        
    private void listenInputMethodStatus() {
        if (getWindow() != null) {
            View decorView = getWindow().getDecorView();
            decorView.getLocationOnScreen(decorViewOutLocation);
            dialogMinOffset = decorViewOutLocation[1] / 3;
            //decorView.addOnLayoutChangeListener(this);
        }
    }

    //          
    private void clearInputMethodStatusListener() {
        if (getWindow() != null) {
           // getWindow().getDecorView().removeOnLayoutChangeListener(this);
        }
    }

   /* @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {

        *//* *                    。
         *                     ,       。         。*//*

        int oldY = decorViewOutLocation[1];
        v.getLocationOnScreen(decorViewOutLocation);
        // decorView     ,                ,         

        Log.e("BBB","   ");
        if (oldY < decorViewOutLocation[1] && decorViewOutLocation[1] - oldY > dialogMinOffset) {
           // super.dismiss();

        }
    }*/

    //       
    private void updateWindow() {
        Window window = getWindow();
        if (window != null) {
            //           
            WindowManager.LayoutParams params = window.getAttributes();
            params.gravity = Gravity.BOTTOM;
            params.width = WindowManager.LayoutParams.MATCH_PARENT;
            window.setAttributes(params);

            window.setWindowAnimations(R.style.anim_dialog_slide_from_bottom);
        }
    }

    //               
    private boolean isOutOfBounds(Context context, MotionEvent event) {
        final int x = (int) event.getX();
        final int y = (int) event.getY();
        final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
        Window window = getWindow();
        if (window == null) return true;
        final View decorView = window.getDecorView();
        return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop))
                || (y > (decorView.getHeight() + slop));
    }

    //      
    private void showInputMethod(EditText editText) {
        inputMethodManager.showSoftInput(editText, -1);
    }

    //      
    private void hideInputMethod(EditText editText) {
        inputMethodManager.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    }

    /**
     *          id
     */
    @LayoutRes
    protected abstract int getContextViewResource();

    /**
     *      Dialog    EditText。
     */
    @Nullable
    protected abstract EditText getEditText();
    @Nullable
    protected abstract TextView getText();



}

本文はこの文章を参考にしてDialogを使って入力法の頂部にぴったり合う入力ボックスを作ってその中の3つのバグを修復しました:1、ソフトキーボードのポップアップと隠しは2まで監視することができなくて、dialogの中で送信ボタンを増加しました.三、dialogをポップアップしてもソフトキーボードをポップアップできません.
主な機能:
1、物理の戻るボタンをクリックして、dialogとソフトキーボードを隠します
2,ソフトキーボードの閉じるボタンをクリックして、ソフトキーボードとdialogを隠す
3、dialogの空白をクリックして、ソフトキーボードとdialogを隠す
4,dialogを弾き出す同時にソフトキーボードを弾き出す
 
ソースダウンロードアドレス
demoダウンロードアドレス