仿映客直播的键盘弹出效果

   很久没写博客了,因为最近有些茫然,好了不废话,说主题,做IM模块的同学应该都知道有一个UI效果一般是跑不掉的,就是发送消息到公屏上

   我现在要在这里展示的就是模仿映客做的一个键盘弹出,发送消息的效果.,先上一张图,不然看不到效果大伙也没兴趣往下看了.


   开始的时候觉得很简单,设置下windowSoftInputMode,写一个EditText,然后点击之后弹出来,点击空白区域消失吗,在一系列的demo之后发觉真的不是那么简单,各种方法试过,什么 ViewTreeObserver,onSizeChanged(),要么就是得不到键盘高度,要么就是视图被压缩了,总之就是都失败了

苦试无果之后,各种百度,google,可惜没有找到一个满意的demo,看了别人说可以用浮层来做,就想到了popupwindow,又一番实验之后发觉不可行,最好决定再试试dialog,然后,嘿,可以了,达到了满意的效果,好了说这么多废话,上代码了,

自定义dialog:

package org.dync.softkeyboarddemo;

import android.app.Dialog;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Field;


/**
 * 文本输入框
 */
public class InputTextDialog extends Dialog {

    public interface OnTextSendListener {
        void onTextSend(String msg, boolean tanmuOpen);
    }

    private TextView confirmBtn;
    private LinearLayout mBarrageArea;
    private EditText messageTextView;
    private static final String TAG = InputTextDialog.class.getSimpleName();
    private Context mContext;
    private InputMethodManager imm;
    private RelativeLayout rlDlg;
    private int mLastDiff = 0;
    private LinearLayout mConfirmArea;
    private OnTextSendListener mOnTextSendListener;
    private boolean mDanmuOpen = false;
//    private final String reg = "[`~@#$%^&*()-_+=|{}':;,/.<>¥…()—【】‘;:”“’。,、]";
//    private Pattern pattern = Pattern.compile(reg);

    public InputTextDialog(Context context, int theme) {
        super(context, theme);
        mContext = context;
        setContentView(R.layout.dialog_input_text);

        messageTextView = (EditText) findViewById(R.id.et_input_message);
        messageTextView.setInputType(InputType.TYPE_CLASS_TEXT);
        //修改下划线颜色
        messageTextView.getBackground().setColorFilter(context.getResources().getColor(R.color.transparent), PorterDuff.Mode.CLEAR);

        try {
            //修改光光标颜色
            Field ft = TextView.class.getDeclaredField("mCursorDrawableRes");
            ft.setAccessible(true);
            ft.set(messageTextView, R.drawable.edit_select);
        } catch (Exception e) {
            e.printStackTrace();
        }

        confirmBtn = (TextView) findViewById(R.id.confrim_btn);
        imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
        confirmBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String msg = messageTextView.getText().toString().trim();
                if (!TextUtils.isEmpty(msg)) {

                    mOnTextSendListener.onTextSend(msg, mDanmuOpen);
                    imm.showSoftInput(messageTextView, InputMethodManager.SHOW_FORCED);
                    imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
                    messageTextView.setText("");
                    dismiss();
                } else {
                    Toast.makeText(mContext, "input can not be empty!", Toast.LENGTH_LONG).show();
                }
                messageTextView.setText(null);
            }
        });

        final Button barrageBtn = (Button) findViewById(R.id.barrage_btn);
        barrageBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mDanmuOpen = !mDanmuOpen;
                if (mDanmuOpen) {
                    barrageBtn.setBackgroundResource(R.drawable.barrage_slider_on);
                } else {
                    barrageBtn.setBackgroundResource(R.drawable.barrage_slider_off);
                }
            }
        });

        mBarrageArea = (LinearLayout) findViewById(R.id.barrage_area);
        mBarrageArea.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDanmuOpen = !mDanmuOpen;
                if (mDanmuOpen) {
                    barrageBtn.setBackgroundResource(R.drawable.barrage_slider_on);
                } else {
                    barrageBtn.setBackgroundResource(R.drawable.barrage_slider_off);
                }
            }
        });

        //监听键盘
        messageTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                switch (actionId) {
                    case KeyEvent.KEYCODE_ENDCALL:
                    case KeyEvent.KEYCODE_ENTER:
                        if (messageTextView.getText().length() > 0) {
//                            mOnTextSendListener.onTextSend("" + messageTextView.getText(), mDanmuOpen);
                            //sendText("" + messageTextView.getText());
                            //imm.showSoftInput(messageTextView, InputMethodManager.SHOW_FORCED);
                            imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
//                            messageTextView.setText("");
                            dismiss();
                        } else {
                            Toast.makeText(mContext, "input can not be empty!", Toast.LENGTH_LONG).show();
                        }
                        return true;
                    case KeyEvent.KEYCODE_BACK:
                        dismiss();
                        return false;
                    default:
                        return false;
                }
            }
        });

        mConfirmArea = (LinearLayout) findViewById(R.id.confirm_area);
        mConfirmArea.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String msg = messageTextView.getText().toString().trim();
                if (!TextUtils.isEmpty(msg)) {

                    mOnTextSendListener.onTextSend(msg, mDanmuOpen);
                    imm.showSoftInput(messageTextView, InputMethodManager.SHOW_FORCED);
                    imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
                    messageTextView.setText("");
                    dismiss();
                } else {
                    Toast.makeText(mContext, "input can not be empty!", Toast.LENGTH_LONG).show();
                }
                messageTextView.setText(null);
            }
        });

        messageTextView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int i, KeyEvent keyEvent) {
                Log.d("My test", "onKey " + keyEvent.getCharacters());
                return false;
            }
        });

        rlDlg = (RelativeLayout) findViewById(R.id.rl_outside_view);
        rlDlg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //点击编辑区域以上的位置,dialog消失
                if (v.getId() != R.id.rl_inputdlg_view)
                    dismiss();
            }
        });

        final LinearLayout rldlgview = (LinearLayout) findViewById(R.id.rl_inputdlg_view);

        //dialog消失键盘会消失,但是键盘消失,dialog不一定消失,比如按软键盘上的消失键,键盘消失,dialog不会消失
        // 所以在这里监听键盘的高度,如果高度为0则表示键盘消失,那么就应该dimiss dialog
        rldlgview.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) {
                Rect r = new Rect();
                //获取当前界面可视部分
                getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
                //获取屏幕的高度
                int screenHeight = getWindow().getDecorView().getRootView().getHeight();
                //此处就是用来获取键盘的高度的, 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数
                int heightDifference = screenHeight - r.bottom;

                if (heightDifference <= 0 && mLastDiff > 0) {
                    //imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
                    dismiss();
                }
                mLastDiff = heightDifference;
            }
        });

        //点击编辑外部layout键盘消失,这个可有可无
//        rldlgview.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
//                dismiss();
//            }
//        });
    }


    public void setmOnTextSendListener(OnTextSendListener onTextSendListener) {
        this.mOnTextSendListener = onTextSendListener;
    }

    @Override
    public void dismiss() {
        super.dismiss();
        //dismiss之前重置mLastDiff值避免下次无法打开
        mLastDiff = 0;
    }

    @Override
    public void show() {
        super.show();
    }
}

直接看这个代码可能有点不太懂,其实原理就是利用dialog的dimiss,因为EditText纯在与dialog中,dialog消失之后,EditText也会消失,那么键盘自然就消失了,注释也写的很详细了,有基础的同学肯定可以看懂的,后面也会把demo地址发出来

dialog_input_text.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_outside_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:id="@+id/rl_inputdlg_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_input_dialog_background"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true">

        <LinearLayout
            android:id="@+id/barrage_area"
            android:orientation="horizontal"
            android:layout_weight="0.3"
            android:layout_gravity="center_vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <Button
                android:id="@+id/barrage_btn"
                android:layout_width="40dp"
                android:layout_marginLeft="10dp"
                android:layout_height="25dp"
                android:layout_marginRight="10dp"
                android:background="@drawable/barrage_slider_off" />
        </LinearLayout>

        <View android:layout_width="0.5dp"
            android:layout_height="match_parent"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="6dp"
            android:layout_marginStart="6dp"
            android:background="@color/colorTransparentBlack"/>

        <EditText
            android:id="@+id/et_input_message"
            android:hint="@string/dialog_input_text_hint"
            android:layout_width="match_parent"
            android:layout_weight="4"
            android:layout_height="wrap_content"
            android:imeActionId="@+id/login"
            android:imeOptions="actionUnspecified"
            android:inputType="text"
            android:maxLength="32"
            android:textColor="@color/black"
            android:maxLines="1"
            android:singleLine="true" />

        <View android:layout_width="0.5dp"
            android:layout_height="match_parent"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="6dp"
            android:layout_marginStart="6dp"
            android:background="@color/colorTransparentBlack"/>

        <LinearLayout
            android:id="@+id/confirm_area"
            android:layout_width="wrap_content"
            android:layout_gravity="center"
            android:layout_height="wrap_content">
            <Button
                android:id="@+id/confrim_btn"
                android:layout_width="50dp"
                android:layout_height="30dp"
                android:background="@drawable/btn_send_message"
                android:gravity="center"
                android:textColor="@color/colorAccent"
                android:text="发送" />
        </LinearLayout>


    </LinearLayout>

</RelativeLayout>

 

这个是输入消息的dialog,嗯,没什么可说的,后面的也不发了,小demo,资源文件也有一些,太久没写博客了,自定义空间方面的东西也没啥好说的,还是直接上地址,大家去copy了看效果吧.

地址:百度网盘


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值