Android 输入法键盘和自定义表情面板

序 、项目有一版本是在优化了直播的聊天功能 ,需要自定义表情面板 。emmmm 。

 

效果图

功能点 :

点击左边的笑脸会弹出表情面板 ,点击输入框会切换到键盘 。 

直接上代码 

package com.developers.superdemo01.smooth;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;

import com.developers.superdemo01.R;

/**
 * @Author yinzh
 * @Date 2020/7/2 13:43
 * @Description 表情输入面板
 */
public class SmoothInputLayout extends LinearLayout {

    public static final int DEFAULT_KEYBOARD_HEIGHT = 387;
    public static final int MIN_KEYBOARD_HEIGHT = 20;
    private static final String SP_KEYBOARD = "keyboard";
    private static final String KEY_HEIGHT = "height";
    private int mMaxKeyboardHeight = Integer.MIN_VALUE;
    private int mDefaultKeyboardHeight = 387;
    private int mMinKeyboardHeight;
    private int mKeyboardHeight;
    private int mInputViewId;
    private View mInputView;
    private boolean mKeyboardOpen = false;
    private boolean mKeyboardOpenOne = false;
    private int mInputPaneId;
    private View mInputPane;
    private OnVisibilityChangeListener mListener;
    private OnKeyboardChangeListener keyboardChangeListener;
    private boolean mAutoSaveKeyboardHeight;
    private KeyboardProcessor mKeyboardProcessor;
    private boolean tShowInputPane = false;

    public SmoothInputLayout(Context context) {
        super(context);
        initView(null);
    }

    public SmoothInputLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(attrs);
    }

    @TargetApi(11)
    public SmoothInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(attrs);
    }

    @TargetApi(21)
    public SmoothInputLayout(Context context, AttributeSet attrs, int defStyleAttr,
                             int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(attrs);
    }

    private void initView(AttributeSet attrs) {
        int defaultInputHeight = (int) (DEFAULT_KEYBOARD_HEIGHT *
                getResources().getDisplayMetrics().density);
        int minInputHeight = (int) (MIN_KEYBOARD_HEIGHT *
                getResources().getDisplayMetrics().density);
        mInputViewId = NO_ID;
        mInputPaneId = NO_ID;
        boolean autoSave;
        TypedArray custom = getContext().obtainStyledAttributes(attrs,
                R.styleable.SmoothInputLayout);
        defaultInputHeight = custom.getDimensionPixelOffset(
                R.styleable.SmoothInputLayout_silDefaultKeyboardHeight, defaultInputHeight);
        minInputHeight = custom.getDimensionPixelOffset(
                R.styleable.SmoothInputLayout_silMinKeyboardHeight, minInputHeight);
        mInputViewId = custom.getResourceId(R.styleable.SmoothInputLayout_silInputView,
                mInputViewId);
        mInputPaneId = custom.getResourceId(R.styleable.SmoothInputLayout_silInputPane,
                mInputPaneId);
        autoSave = custom.getBoolean(R.styleable.SmoothInputLayout_silAutoSaveKeyboardHeight,
                true);
        custom.recycle();
        setDefaultKeyboardHeight(defaultInputHeight);
        setMinKeyboardHeight(minInputHeight);
        setAutoSaveKeyboardHeight(autoSave);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (mInputViewId != NO_ID) {
            setInputView(findViewById(mInputViewId));
        }
        if (mInputPaneId != NO_ID) {
            setInputPane(findViewById(mInputPaneId));
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if(mMaxKeyboardHeight > 3000){ // 此处代码是为了限制横竖屏切换的时候值过高问题 。
            mMaxKeyboardHeight = heightSize;
        }
        if (heightSize > mMaxKeyboardHeight) {
            mMaxKeyboardHeight = heightSize;
        }
        final int heightChange = mMaxKeyboardHeight - heightSize;
        Log.i("SSSSSSSSSSSS", heightSize + "= heightSize=" + mMaxKeyboardHeight + "= mMaxKeyboardHeight = " + heightChange + "=heightChange = " + mMinKeyboardHeight + "=mMinKeyboardHeight");
        if (heightChange > mMinKeyboardHeight) {
            if (mKeyboardHeight != heightChange) {
                mKeyboardHeight = heightChange;
                saveKeyboardHeight();
            }
            mKeyboardOpen = true;
            // 输入法弹出,隐藏功能面板
            if (mInputPane != null && mInputPane.getVisibility() == VISIBLE) {
                mInputPane.setVisibility(GONE);
                if (mListener != null)
                    mListener.onVisibilityChange(GONE);
            }
        } else {
            mKeyboardOpen = false;
            if (tShowInputPane) {
                tShowInputPane = false;
                if (mInputPane != null && mInputPane.getVisibility() == GONE) {
                    updateLayout();
                    mInputPane.setVisibility(VISIBLE);
                    if (mListener != null)
                        mListener.onVisibilityChange(VISIBLE);
                    forceLayout();
                }
            }
        }

        Log.i("SSSSSSSSSSSS", mKeyboardOpen + "=========");
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (keyboardChangeListener != null)
            keyboardChangeListener.onKeyboardChanged(mKeyboardOpen);
    }

    /**
     * 获取键盘SP
     *
     * @return 键盘SP
     */
    private SharedPreferences getKeyboardSharedPreferences() {
        return getContext().getSharedPreferences(SP_KEYBOARD, Context.MODE_PRIVATE);
    }

    /**
     * 存储键盘高度
     */
    private void saveKeyboardHeight() {
        if (mAutoSaveKeyboardHeight)
            getKeyboardSharedPreferences().edit().putInt(KEY_HEIGHT, mKeyboardHeight).commit();
        else {
            if (mKeyboardProcessor != null)
                mKeyboardProcessor.onSaveKeyboardHeight(mKeyboardHeight);
        }
    }

    /**
     * 更新子项高度
     */
    private void updateLayout() {
        if (mInputPane == null)
            return;
        if (mKeyboardHeight == 0)
            mKeyboardHeight = getKeyboardHeight(mDefaultKeyboardHeight);
        ViewGroup.LayoutParams layoutParams = mInputPane.getLayoutParams();
        if (layoutParams != null) {
            layoutParams.height = mKeyboardHeight;
            mInputPane.setLayoutParams(layoutParams);
        }
    }

    private int getKeyboardHeight(int defaultHeight) {
        if (mAutoSaveKeyboardHeight)
            return getKeyboardSharedPreferences().getInt(KEY_HEIGHT, defaultHeight);
        else
            return mKeyboardProcessor != null ?
                    mKeyboardProcessor.getSavedKeyboardHeight(defaultHeight) : defaultHeight;
    }

    /**
     * 设置默认系统输入面板高度
     *
     * @param height 输入面板高度
     */
    public void setDefaultKeyboardHeight(int height) {
        if (mDefaultKeyboardHeight != height)
            mDefaultKeyboardHeight = height;
    }

    /**
     * 设置最小系统输入面板高度
     *
     * @param height 输入面板高度
     */
    public void setMinKeyboardHeight(int height) {
        if (mMinKeyboardHeight != height)
            mMinKeyboardHeight = height;
    }

    /**
     * 设置输入框
     *
     * @param edit 输入框
     */
    public void setInputView(View edit) {
        if (mInputView != edit)
            mInputView = edit;
    }

    /**
     * 设置特殊输入面板
     *
     * @param pane 面板
     */
    public void setInputPane(View pane) {
        if (mInputPane != pane)
            mInputPane = pane;
    }

    /**
     * 设置面板可见改变监听
     *
     * @param listener 面板可见改变监听
     */
    public void setOnVisibilityChangeListener(OnVisibilityChangeListener listener) {
        mListener = listener;
    }

    /**
     * 设置键盘改变监听
     *
     * @param listener 键盘改变监听
     */
    public void setOnKeyboardChangeListener(OnKeyboardChangeListener listener) {
        keyboardChangeListener = listener;
    }

    /**
     * 设置自动保存键盘高度
     *
     * @param auto 是否自动
     */
    public void setAutoSaveKeyboardHeight(boolean auto) {
        mAutoSaveKeyboardHeight = auto;
    }

    /**
     * 设置键盘处理器
     * 仅在关闭自动保存键盘高度时设置的处理器才有效{@link #setAutoSaveKeyboardHeight(boolean)}
     *
     * @param processor 处理器
     */
    public void setKeyboardProcessor(KeyboardProcessor processor) {
        mKeyboardProcessor = processor;
    }

    /**
     * 是否输入法已打开
     *
     * @return 是否输入法已打开
     */
    public boolean isKeyBoardOpen() {

        return mKeyboardOpen;
    }

    public boolean isKeyboardOpenOne() {
        return mKeyboardOpenOne;
    }

    public void setmKeyboardOpenOne(boolean mKeyboardOpenOne) {
        this.mKeyboardOpenOne = mKeyboardOpenOne;
    }

    public void setKeyboardOpen(boolean mKeyboardOpen) {
        this.mKeyboardOpen = mKeyboardOpen;
    }

    /**
     * 是否特殊输入面板已打开
     *
     * @return 特殊输入面板已打开
     */
    public boolean isInputPaneOpen() {
        return mInputPane != null && mInputPane.getVisibility() == VISIBLE;
    }

    /**
     * 关闭特殊输入面板
     */
    public void closeInputPane() {
        if (isInputPaneOpen()) {
            mInputPane.setVisibility(GONE);
            if (mListener != null)
                mListener.onVisibilityChange(GONE);
        }
    }

    /**
     * 显示特殊输入面板
     *
     * @param focus 是否让输入框拥有焦点
     */
    public void showInputPane(boolean focus) {
        if (isKeyBoardOpen()) {
            tShowInputPane = true;
            InputMethodManager imm = ((InputMethodManager) (getContext()
                    .getSystemService(Context.INPUT_METHOD_SERVICE)));
            if (imm != null) {
                imm.hideSoftInputFromWindow(getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
            }

        } else {
            if (mInputPane != null && mInputPane.getVisibility() == GONE) {
                updateLayout();
                mInputPane.setVisibility(VISIBLE);
                if (mListener != null)
                    mListener.onVisibilityChange(VISIBLE);
            }
        }
        if (focus) {
            if (mInputView != null) {
                mInputView.requestFocus();
                mInputView.requestFocusFromTouch();
            }
        } else {
            if (mInputView != null) {
                setFocusable(true);
                setFocusableInTouchMode(true);
                mInputView.clearFocus();
            }
        }
    }

    /**
     * 关闭键盘
     *
     * @param clearFocus 是否清除输入框焦点
     */
    public void closeKeyboard(boolean clearFocus) {
        InputMethodManager imm = ((InputMethodManager) (getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE)));
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindowToken(),
                    InputMethodManager.HIDE_NOT_ALWAYS);
        }
        if (clearFocus && mInputView != null) {
            setFocusable(true);
            setFocusableInTouchMode(true);
            mInputView.clearFocus();
        }
    }

    /**
     * 打开键盘
     */
    public void showKeyboard() {
        if (mInputView == null) {
            return;
        }
        mInputView.requestFocus();
        mInputView.requestFocusFromTouch();
        InputMethodManager imm = ((InputMethodManager) (getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE)));
        if (imm != null) {
            imm.showSoftInput(mInputView, InputMethodManager.SHOW_IMPLICIT);
        }
    }

    /**
     * 面板可见改变监听
     */
    public interface OnVisibilityChangeListener {
        void onVisibilityChange(int visibility);
    }

    /**
     * 键盘改变监听
     */
    public interface OnKeyboardChangeListener {
        void onKeyboardChanged(boolean open);
    }

    /**
     * 键盘处理器
     */
    public interface KeyboardProcessor {
        /**
         * 存储键盘高度
         *
         * @param height 高度
         */
        void onSaveKeyboardHeight(int height);

        /**
         * 获取存储的键盘高度
         *
         * @param defaultHeight 默认高度
         * @return 键盘高度
         */
        int getSavedKeyboardHeight(int defaultHeight);
    }
}

 

注意事项:

需要在配置清单设置 

  android:configChanges="keyboardHidden|orientation|screenSize"
            android:windowSoftInputMode="adjustResize" >

 

github地址 :

https://github.com/spuermax/SuperDemo01

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值