Android实现弹窗中有输入框填写内容

龙旋

共 15143字,需浏览 31分钟

 · 2021-10-11

一、前言:


最近,在做社区的时候,遇到点击评论的时候,弹起输入框,填写文字,键盘的弹起和隐藏一直控制不好,借用同事的方法,总结使用一下。

效果图如下:


二、代码:


1、主类方法调用:

public class MainActivity extends AppCompatActivity {    //输入弹窗    private InputTextMsgDialog inputTextMsgDialog;    private Timer timer;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button btn = findViewById(R.id.btn);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                showSoft();            }        });    }    /**     * 弹起键盘     */    private void showSoft() {        try {            if (inputTextMsgDialog == null) {                inputTextMsgDialog = new InputTextMsgDialog(MainActivity.this, R.style.dialog_center);                inputTextMsgDialog.setHint("请输入聊天内容");            }            if (timer == null) {                timer = new Timer();            }            timer.schedule(new TimerTask() {                @Override                public void run() {                    runOnUiThread(new Runnable() {                        @Override                        public void run() {                            inputTextMsgDialog.showKeyboard();                        }                    });                }            }, 100);            inputTextMsgDialog.show();            inputTextMsgDialog.setmOnTextSendListener(new InputTextMsgDialog.OnTextSendListener() {                @Override                public void onInputTextString(String msg) {                    //  LogUtils.d("msg===========" + msg);                }                @Override                public void onClickSend(String message) {                    String comment = message.replace(" ", "");                    if (!TextUtils.isEmpty(comment)) {                        Toast.makeText(MainActivity.this, comment, Toast.LENGTH_SHORT).show();                    } else {                        Toast.makeText(MainActivity.this, "请输入聊天内容", Toast.LENGTH_SHORT).show();                    }                }            });        } catch (Exception e) {            e.printStackTrace();        }    }}

注意:
  • 键盘弹起必须主线程,而且是要延时弹起;


2、stytle 风格 dialog_center


3、InputTextMsgDialog文件

public class InputTextMsgDialog extends AppCompatDialog {private Context mContext;private InputMethodManager imm;private ScrollViewEditText messageTextView;private TextView confirmBtn;private KeyboardLayout rlDlg;private int mLastDiff = 0;private int maxNumber = 150;public interface OnTextSendListener {void onInputTextString(String msg);void  onClickSend(String message);    }private OnTextSendListener mOnTextSendListener;public InputTextMsgDialog(@NonNull Context context, int theme) {super(context, theme);this.mContext = context;        init();        setLayout();    }/**     * 最大输入字数  默认200     */@SuppressLint("SetTextI18n")public void setMaxNumber(int maxNumber) {this.maxNumber = maxNumber;    }/**     * 设置输入提示文字     */public void setHint(String text) {        messageTextView.setHint(text);    }/*设置输入的文字*/public void setText(String text) {        messageTextView.setText(text);    }public void setTextInit(){        rlDlg.mHasInit=false;    }/**     * 设置按钮的文字  默认为:发送     */public void setBtnText(String text) {        confirmBtn.setText(text);    }private void init() {        setContentView(R.layout.dialog_input_text_msg);        getWindow().getDecorView().setPadding(0,0,0,0);        WindowManager windowManager = getWindow().getWindowManager();        Display display = windowManager.getDefaultDisplay();        WindowManager.LayoutParams lp = getWindow().getAttributes();        lp.width = WindowManager.LayoutParams.MATCH_PARENT;        getWindow().setAttributes(lp);        messageTextView = findViewById(R.id.et_input_message);        ConstraintLayout rldlgview =findViewById(R.id.rl_inputdlg_view);        messageTextView.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {            }@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {                Editable editable = messageTextView.getText();int len = editable.length();if(len > maxNumber) {                    Toast.makeText(mContext,"最大可输入"+maxNumber+"个字符",Toast.LENGTH_SHORT);int selEndIndex = Selection.getSelectionEnd(editable);                    String str = editable.toString();//截取新字符串                    String newStr = str.substring(0,maxNumber);                    messageTextView.setText(newStr);                    editable = messageTextView.getText();//新字符串的长度int newLen = editable.length();//旧光标位置超过字符串长度if(selEndIndex > newLen)                    {                        selEndIndex = editable.length();                    }//设置新光标所在的位置                    Selection.setSelection(editable, selEndIndex);                }            }@Overridepublic void afterTextChanged(Editable editable) {if (editable.length() == 0) {                    confirmBtn.setTextColor(mContext.getResources().getColor(R.color.color_FFCCCCCC));                } else {                    confirmBtn.setTextColor(mContext.getResources().getColor(R.color.color_FF666666));                }            }        });        confirmBtn = (TextView) findViewById(R.id.confrim_btn);        imm = (InputMethodManager) mContext.getSystemService(INPUT_METHOD_SERVICE);        messageTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {@Overridepublic boolean onEditorAction(TextView v, int actionId, KeyEvent event) {switch (actionId) {case KeyEvent.KEYCODE_ENDCALL:case KeyEvent.KEYCODE_ENTER://                        if (messageTextView.getText().length() > maxNumber) {//                            Toast.makeText(mContext, "超过最大字数限制", Toast.LENGTH_LONG).show();//                            return true;//                        }//                        if (messageTextView.getText().length() > 0) {//                            imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);//                            dismiss();//                        } else {//                            Toast.makeText(mContext, "请输入文字", Toast.LENGTH_LONG).show();//                        }return true;case KeyEvent.KEYCODE_BACK:                        dismiss();return false;default:return false;                }            }        });        messageTextView.setOnKeyListener(new View.OnKeyListener() {@Overridepublic boolean onKey(View view, int i, KeyEvent keyEvent) {                Log.d("My test", "onKey " + keyEvent.getCharacters());return false;            }        });        confirmBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {                mOnTextSendListener.onClickSend(messageTextView.getText().toString().trim());                imm.showSoftInput(messageTextView, InputMethodManager.SHOW_FORCED);                imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);                messageTextView.setText("");                dismiss();            }        });        rlDlg = findViewById(R.id.rl_outside_view);        findViewById(R.id.rl_background).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {                mOnTextSendListener.onInputTextString(messageTextView.getText().toString().trim());                imm.showSoftInput(messageTextView, InputMethodManager.SHOW_FORCED);                imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);                messageTextView.setText("");                dismiss();            }        });        rlDlg.setOnkbdStateListener(new KeyboardLayout.onKybdsChangeListener() {@Overridepublic void onKeyBoardStateChange(int state) {switch (state) {case KeyboardLayout.KEYBOARD_STATE_HIDE://    Toast.makeText(getApplicationContext(), "软键盘隐藏", Toast.LENGTH_SHORT).show();//   Log.e("KeyboardLayout","KeyboardLayout----软键盘隐藏");                        mOnTextSendListener.onInputTextString(messageTextView.getText().toString().trim());                        messageTextView.setText("");if(isShowing()){                            dismiss();                        }break;case KeyboardLayout.KEYBOARD_STATE_SHOW://   Toast.makeText(getApplicationContext(), "软键盘弹起", Toast.LENGTH_SHORT).show();break;                }            }        });        rldlgview.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {                imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);                dismiss();            }        });        setOnKeyListener(new OnKeyListener() {@Overridepublic boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) {if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.getRepeatCount() == 0) {                    dismiss();                }return false;            }        });    }public void showKeyboard() {if(messageTextView!=null){//设置可获得焦点            messageTextView.setFocusable(true);            messageTextView.setFocusableInTouchMode(true);//请求获得焦点            messageTextView.requestFocus();//调用系统输入法//            InputMethodManager imm = (InputMethodManager) mContext.getSystemService(INPUT_METHOD_SERVICE);//            imm.showSoftInput(messageTextView, 0);//            imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);            InputMethodManager inputMethodManager=(InputMethodManager)mContext. getSystemService(Context.INPUT_METHOD_SERVICE);            inputMethodManager.showSoftInput(messageTextView, InputMethodManager.HIDE_NOT_ALWAYS);        }    }private void setLayout() {        getWindow().setGravity(Gravity.BOTTOM);        WindowManager m = getWindow().getWindowManager();        Display d = m.getDefaultDisplay();        WindowManager.LayoutParams p = getWindow().getAttributes();        p.width = WindowManager.LayoutParams.MATCH_PARENT;        p.height = WindowManager.LayoutParams.WRAP_CONTENT;        getWindow().setAttributes(p);        setCancelable(true);        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);    }public void setmOnTextSendListener(OnTextSendListener onTextSendListener) {this.mOnTextSendListener = onTextSendListener;    }@Overridepublic void dismiss() {super.dismiss();//dismiss之前重置mLastDiff值避免下次无法打开        mLastDiff = 0;        rlDlg.setmHasInit(false);        rlDlg.setmHasKeybord(false);    }@Overridepublic void show() {super.show();    }}

dialog_input_text_msg.xml 布局文件
xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/rl_outside_view"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal">android:fillViewport="true"android:layout_width="match_parent"android:layout_height="match_parent">android:id="@+id/rl_background"android:layout_width="match_parent"android:layout_height="match_parent">android:id="@+id/rl_inputdlg_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="#ffffff"android:orientation="vertical">app:layout_constraintRight_toLeftOf="@id/confrim_btn"app:layout_constraintLeft_toLeftOf="parent"android:layout_toLeftOf="@id/confrim_btn"android:id="@+id/et_input_message"android:layout_width="0dp"android:layout_height="wrap_content"android:maxHeight="100dp"android:background="#ffffff"android:gravity="top"android:hint="喜欢就要大声说出"android:imeOptions="flagNoExtractUi"android:lineSpacingMultiplier="1.2"android:maxLength="2000"android:maxLines="6"android:minHeight="45dp"android:paddingLeft="15dp"android:paddingTop="10dp"android:paddingRight="15dp"android:paddingBottom="10dp"android:scrollbars="vertical"android:textColorHint="#ffcccccc"android:textColor="#FF333333"android:textSize="14dp"tools:ignore="InvalidImeActionId,MissingConstraints" />app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toRightOf="@id/et_input_message"app:layout_constraintRight_toRightOf="parent"android:layout_alignParentRight="true"android:textColor="#ffcccccc"android:id="@+id/confrim_btn"android:layout_width="45dp"android:layout_height="45dp"android:background="#ffffff"android:gravity="center"android:text="发送" />

4、ScrollViewEditText 文件

@SuppressLint("AppCompatCustomView")public class ScrollViewEditText extends EditText {//滑动距离的最大边界private int mOffsetHeight;//是否到顶或者到底的标志private boolean mBottomFlag = false;public ScrollViewEditText(Context context) {super(context);        init();    }public ScrollViewEditText(Context context, AttributeSet attrs) {super(context, attrs);        init();    }public ScrollViewEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);        init();    }private void init() {    }@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int paddingTop;int paddingBottom;int mHeight;int mLayoutHeight;//获得内容面板        Layout mLayout = getLayout();//获得内容面板的高度        mLayoutHeight = mLayout.getHeight();//获取上内边距        paddingTop = getTotalPaddingTop();//获取下内边距        paddingBottom = getTotalPaddingBottom();//获得控件的实际高度        mHeight = getHeight();//计算滑动距离的边界        mOffsetHeight = mLayoutHeight + paddingTop + paddingBottom - mHeight;    }@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN)//如果是新的按下事件,则对mBottomFlag重新初始化            mBottomFlag = false;//如果已经不要这次事件,则传出取消的信号,这里的作用不大if (mBottomFlag)            event.setAction(MotionEvent.ACTION_CANCEL);return super.dispatchTouchEvent(event);    }@Overridepublic boolean onTouchEvent(MotionEvent event) {boolean result = super.onTouchEvent(event);//如果是需要拦截,则再拦截,这个方法会在onScrollChanged方法之后再调用一次if (!mBottomFlag)            getParent().requestDisallowInterceptTouchEvent(true);return result;    }@Overrideprotected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {super.onScrollChanged(horiz, vert, oldHoriz, oldVert);if (vert == mOffsetHeight || vert == 0) {//这里触发父布局或祖父布局的滑动事件            getParent().requestDisallowInterceptTouchEvent(false);            mBottomFlag = true;        }    }}

5、KeyboardLayout文件

public class KeyboardLayout extends RelativeLayout {private static final String TAG = KeyboardLayout.class.getSimpleName();public static final byte KEYBOARD_STATE_SHOW = -3;public static final byte KEYBOARD_STATE_HIDE = -2;public static final byte KEYBOARD_STATE_INIT = -1;public boolean mHasInit;private boolean mHasKeybord;private int mHeight;private onKybdsChangeListener mListener;public void setmHasInit(boolean mHasInit) {this.mHasInit = mHasInit;    }public void setmHasKeybord(boolean mHasKeybord) {this.mHasKeybord = mHasKeybord;    }public KeyboardLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);    }public KeyboardLayout(Context context, AttributeSet attrs) {super(context, attrs);    }public KeyboardLayout(Context context) {super(context);    }/** * set keyboard state listener */public void setOnkbdStateListener(onKybdsChangeListener listener) {        mListener = listener;    }@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if (!mHasInit) {            mHasInit = true;            mHeight = b;if (mListener != null) {                mListener.onKeyBoardStateChange(KEYBOARD_STATE_INIT);            }        } else {            mHeight = mHeight < b ? b : mHeight;        }if (mHasInit && mHeight > b) {            mHasKeybord = true;if (mListener != null) {                mListener.onKeyBoardStateChange(KEYBOARD_STATE_SHOW);            }            Log.w(TAG, "show keyboard.......");        }if (mHasInit && mHasKeybord && mHeight == b) {            mHasKeybord = false;if (mListener != null) {                mListener.onKeyBoardStateChange(KEYBOARD_STATE_HIDE);            }            Log.w(TAG, "hide keyboard.......");        }    }public interface onKybdsChangeListener {public void onKeyBoardStateChange(int state);    }}

6、handler延时弹起代码示例:

private final int BOND = 1;private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case BOND:                InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);                inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);break;        }    }};InputPwdDialog inputPwdDialog = new InputPwdDialog(context,Gravity.BOTTOM,R.layout.item_dialog); inputPwdDialog.show();handler.sendEmptyMessageDelayed(BOND,100);

源码地址:
https://gitee.com/luoyanyong/InputMsgDialog

到这里就结束啦。
浏览 149
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报