Android聊天输入框控件

public class ChatInputWidget extends LinearLayout implements OnClickListener {
    private final String TAG = getClass().getSimpleName();
    private ViewPager mEmojiPager;
    private GifEditText mEditText;
    private ImageView mEmojiImageView;
    private Button mSendButton;
    private View pagerView;
    private CircleIndicator circleIndicator;

    private Handler handler = new Handler();
    private List<Emoji> mEmojiList;

    private static final String FILE_NAME = "emoji.txt";
    private static final String GIFT_RES_FILE_PATH = "emoji";
    private static final String ASSETS_FILE_NAME = GIFT_RES_FILE_PATH + "/" + FILE_NAME;
    private final int pagerNum = 10;

    protected Context mContext;
//    protected InputMethodManager inputManager;

    private ChatInputMenuListener mListener;
    private int mToUserId;
    private int mToVipLevel;
    private String toUserName;

    public String getToUserName() {
        return toUserName;
    }

    public void setToUserName(String toUserName) {
        this.toUserName = toUserName;
    }

    public void setToVipLevel(int toVipLevel) {
        this.mToVipLevel = toVipLevel;
    }

    public ChatInputWidget(Context context) {
        super(context);
        if (context instanceof Activity) {
            ((Activity) context).getLayoutInflater().inflate(R.layout.widget_chat_input, this);
        } else {
            inflate(context, R.layout.widget_chat_input, this);
        }
        initView(context);
    }

    public ChatInputWidget(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (context instanceof Activity) {
            ((Activity) context).getLayoutInflater().inflate(R.layout.widget_chat_input, this);
        } else {
            inflate(context, R.layout.widget_chat_input, this);
        }
        initView(context);
    }

    private void initView(Context context) {
        this.mContext = context;
//        inputManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

        mEditText = (GifEditText) findViewById(R.id.chat_et_message);
        mEmojiPager = (ViewPager) findViewById(R.id.chat_vp_face_pager);
        mEmojiImageView = (ImageView) findViewById(R.id.chat_iv_face);
        mSendButton = (Button) findViewById(R.id.chat_bt_send);
        pagerView = findViewById(R.id.rl_chat_pager);
        circleIndicator = (CircleIndicator) findViewById(R.id.indicator_chat_emoji);

    }

    public void init() {
        mSendButton.setOnClickListener(this);
        mEmojiImageView.setOnClickListener(this);
        mEditText.setOnClickListener(this);
        mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    hideEmojicon();
                }
            }
        });

        mEmojiList = getExpressionRes();
        List<View> views = new ArrayList<>();

        int pagerSize;

        if (mEmojiList.size() % pagerNum == 0) {
            pagerSize = mEmojiList.size() / pagerNum;
        } else {
            pagerSize = mEmojiList.size() / pagerNum + 1;
        }

//        LogUtil.w(TAG, "pagerSize === " + pagerSize);

        for (int i = 0; i < pagerSize; i++) {
            if (i == pagerSize - 1) {
                views.add(getGridChildView(mEmojiList.subList(i * pagerNum, mEmojiList.size())));
            } else {
                views.add(getGridChildView(mEmojiList.subList(i * pagerNum, (i + 1) * pagerNum)));
            }
        }
        mEmojiPager.setAdapter(new EmojiPagerAdapter(views));
        circleIndicator.setViewPager(mEmojiPager);
    }

    /**
     * 显示或隐藏表情页
     */
    private void toggleEmojicon() {
        if (pagerView.getVisibility() == View.GONE) {
            hideKeyboard();
            handler.postDelayed(new Runnable() {
                public void run() {
                    showEmojicon();
                }
            }, 100);
        } else {
            hideEmojicon();
            handler.postDelayed(new Runnable() {
                public void run() {
                    showKeyboard();
                }
            }, 100);
        }
    }

    /**
     * 隐藏表情页
     */
    public void hideEmojicon() {
        pagerView.setVisibility(View.GONE);
        mEmojiImageView.setSelected(false);
    }

    private void showEmojicon() {
        pagerView.setVisibility(View.VISIBLE);
        mEmojiImageView.setSelected(true);
    }

    /**
     * 隐藏表情按钮
     */
    public void hideEmojiButton() {
        mEmojiImageView.setVisibility(View.GONE);
    }

    public void setHint(String hint) {
        mEditText.setHint(hint);
    }

    public void setHint(int resid) {
        mEditText.setHint(resid);
    }

    public String getText() {
        return mEditText.getText().toString();
    }

    public void setText(String text) {
        mEditText.setText(text);
        if (text != null) {    //光标移到最后
            mEditText.setSelection(text.length());
        }
    }

    public void setText(int resid) {
        mEditText.setText(resid);
    }

    public void setFocus() {
        mEditText.setFocusable(true);
        mEditText.setFocusableInTouchMode(true);
        mEditText.requestFocus();
        mEditText.requestFocusFromTouch();
        mEditText.postDelayed(new Runnable() {
            @Override
            public void run() {
                AppUtil.showInputMethod(mEditText);
            }
        }, 50);
    }

    public View getEditText() {
        return mEditText;
    }

    /**
     * 隐藏软键盘
     */
    public void hideKeyboard() {
        AppUtil.hideInputMethod(mEditText);
    }

    public void showKeyboard() {
        AppUtil.showInputMethod(mEditText);
    }

    /**
     * 系统返回键被按时调用此方法
     *
     * @return 返回false表示返回键时扩展菜单栏时打开状态,true则表示按返回键时扩展栏是关闭状态<br/>
     * 如果返回时打开状态状态,会先关闭扩展栏再返回值
     */
    public boolean onBackPressed() {
        if (pagerView.getVisibility() == View.VISIBLE) {    //隐藏表情
            hideEmojicon();
            return false;
        } else {
            return true;
        }

    }

    private void sendMessage() {
        //通过回调通知发送消息
        if (mListener != null) {
            String message = StrUtil.escapeForXML(mEditText.getText().toString());
            if (mListener.onSendMessage(message, mToUserId, mToVipLevel, toUserName)) {
                //清空内容
                mEditText.setText(null);
            }
        }
    }

    public void setToUserId(int userId) {
        mToUserId = userId;
    }

    public int getToUserId() {
        return mToUserId;
    }

    /**
     * 清除输入框内容
     */
    public void clearText() {
        mEditText.setText(null);
    }

    public void setChatInputMenuListener(ChatInputMenuListener listener) {
        this.mListener = listener;
    }

    private void insertEmoji(String name) {
        final int pos = mEditText.getSelectionStart();
        final String faceString = "[$" + name + "$]";
        final Editable text = (Editable) mEditText.getText();
        text.insert(pos, faceString);
        final GifDrawable drawable = EmojiHelper.getInstance().getGifDrawable(name);
        if (drawable != null) {
            final ImageSpan gifSpan = new GifImageSpan(drawable);
            text.setSpan(gifSpan, pos, pos + faceString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }

    private List<Emoji> getExpressionRes() {
        List<Emoji> reslist = new ArrayList<>();
        String emojiJson = FileUtil.readAssetsByName(mContext, ASSETS_FILE_NAME);

        try {
            reslist = parseGiftList(new JSONObject(emojiJson));
        } catch (Exception e) {
            LogUtil.e(TAG, "read local gift error:" + e.toString());
        }
        return reslist;
    }

    private List<Emoji> parseGiftList(JSONObject json) throws Exception {
        List<Emoji> giftList = new ArrayList<>();
        JSONArray jsonArray = json.getJSONArray("emoji");
        if (jsonArray != null) {
            for (int i = 0; i < jsonArray.length(); i++) {
                giftList.add(parseGift(jsonArray.getJSONObject(i)));
            }
        }
        return giftList;
    }

    private Emoji parseGift(JSONObject json) throws Exception {
        Emoji emoji = new Emoji();
        emoji.setId(json.getString("id"));
        emoji.setName(json.getString("name"));
        return emoji;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.chat_iv_face:
                toggleEmojicon();
                break;
            case R.id.chat_et_message:
                hideEmojicon();
                break;
            case R.id.chat_bt_send:
                sendMessage();
                break;
        }
    }

    /**
     * 获取表情的gridview的子view
     *
     * @param
     * @return
     */
    private View getGridChildView(List<Emoji> list) {
        final EmojiGridAdapter expressionAdapter = new EmojiGridAdapter(mContext, list);
        GridView gridView = (GridView) LayoutInflater.from(mContext).inflate(R.layout.layout_emoji_grid, null);
        gridView.setAdapter(expressionAdapter);
        gridView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                try {
                    // 文字输入框可见时,才可输入表情
                    if (mEditText.getVisibility() == View.VISIBLE) {
                        insertEmoji(expressionAdapter.getItem(position).getId());
                    }
                } catch (Exception e) {
                }

            }
        });
        return gridView;
    }

    public class EmojiPagerAdapter extends PagerAdapter {

        private List<View> views;

        public EmojiPagerAdapter(List<View> views) {
            this.views = views;
        }

        @Override
        public int getCount() {
            return views.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ((ViewPager) container).addView(views.get(position));
            return views.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ((ViewPager) container).removeView(views.get(position));

        }

    }

    private class EmojiGridAdapter extends QuickAdapter<Emoji> {

        public EmojiGridAdapter(Context context, List<Emoji> objects) {
            super(context, R.layout.item_emoji, objects);
        }

        @Override
        protected void convert(BaseAdapterHelper helper, Emoji item) {
            helper.setText(R.id.emoji_tv_expression, item.getName());
            helper.setImageDrawable(R.id.emoji_iv_expression, EmojiHelper.getInstance().getPngDrawable(item.getId()));
        }

    }

    public int getChatInputLength() {
        if (null != mEditText) {
            return mEditText.getChatInputLength();
        } else {
            return 0;
        }
    }

    public interface ChatInputMenuListener {
        /**
         * 发送消息按钮点击
         *
         * @param content  文本内容
         * @param toUserId
         */
        boolean onSendMessage(String content, int toUserId, int toVipLevel, String toUserName);

    }

}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:skin="http://schemas.android.com/android/skin"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@drawable/skin_label_gray_bg"
              android:orientation="vertical"
              skin:enable="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:gravity="center_vertical|right"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.00"
            android:background="@drawable/skin_label_white_bg"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingBottom="8dp"
            android:paddingRight="5dp"
            android:paddingTop="8dp"
            skin:enable="true">

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.00"
                android:gravity="center_vertical|right"
                android:orientation="horizontal">

                <!-- <LinearLayout
                    android:id="@+id/chat_ll_to"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal" >

                    <TextView
                        android:id="@+id/chat_tv_to"
                        android:layout_width="60dp"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_vertical"
                        android:layout_marginLeft="5dp"
                        android:drawablePadding="5dp"
                        android:drawableRight="@drawable/small_up_arrow"
                        android:ellipsize="end"
                        android:gravity="right"
                        android:singleLine="true"
                        android:text="@string/chat_text_toall"
                        android:textColor="@color/common_blue"
                        android:textSize="14sp" />

                    <View
                        android:layout_width="1px"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="5dp"
                        android:background="@color/line_view_item" />
                </LinearLayout> -->

                <com.gift.view.GifEditText
                    android:id="@+id/chat_et_message"
                    style="?android:attr/editTextStyle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:background="@null"
                    android:focusable="true"
                    android:focusableInTouchMode="true"
                    android:gravity="center_vertical"
                    android:hint="@string/chat_hint_message"
                    android:imeOptions="actionNone"
                    android:inputType="textMultiLine"
                    android:maxHeight="100dp"
                    android:maxLength="200"
                    android:textColor="@color/text_content"
                    android:textColorHint="@color/text_prompt_input"
                    android:textSize="14sp"/>
            </LinearLayout>

            <ImageView
                android:id="@+id/chat_iv_face"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="5dp"
                android:src="@drawable/button_selector_chat_face"/>
        </LinearLayout>

        <Button
            android:id="@+id/chat_bt_send"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginLeft="5dp"
            android:background="@drawable/skin_button_bg_white"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:text="@string/chat_text_send"
            android:textColor="@color/button_text_color"
            android:textSize="14sp"
            skin:enable="true"/>
    </LinearLayout>

    <RelativeLayout
        android:id="@+id/rl_chat_pager"
        android:layout_width="match_parent"
        android:layout_height="270dp"
        android:background="@color/white"
        android:paddingBottom="27dp"
        android:visibility="gone"
        >

        <android.support.v4.view.ViewPager
            android:id="@+id/chat_vp_face_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:persistentDrawingCache="animation"
            />

        <com.gift.view.infiniteview.CircleIndicator
            android:id="@+id/indicator_chat_emoji"
            android:layout_width="match_parent"
            android:layout_height="6dp"
            android:layout_alignParentBottom="true"
            app:ci_background="@color/banner_indicator_selected"
            app:ci_gravity="center"
            app:ci_margin="5dp"
            app:ci_mode="solo"
            app:ci_radius="3dp"
            app:ci_selected_background="@color/text_orange"
            />

    </RelativeLayout>

</LinearLayout>

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注