啥也不多说,先上图
先说实现的功能:emoji表情和图片表情的显示(未实现gif表情的显示)、软键盘高度的获取、软键盘和表情面板的完美切换(不会抖动)、微信公众号键盘的展示。
该dome主要针对做im通讯的童鞋对表情实现的各种纠结给点启发。。。demo中用到了:钉钉、微信、网易中的表情图片。在这里谢谢了!如有不足或侵犯到您的权限请及时告知。谢谢!
面板布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <View android:layout_width="match_parent" android:layout_height="1.0px" android:background="@color/line_view_bg" /> <RelativeLayout android:id="@+id/top_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/the_color_white" android:gravity="center" android:visibility="visible" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="bottom" android:orientation="horizontal" > <ImageView android:id="@+id/public_num_soft" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|bottom" android:layout_margin="10dp" android:src="@drawable/icon_menu_top" android:visibility="gone" /> <View android:id="@+id/public_num_view" android:layout_width="1.0px" android:layout_height="match_parent" android:background="@color/layout_division_view" android:visibility="visible" /> <LinearLayout android:id="@+id/publicNumLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center" android:orientation="horizontal" android:visibility="gone" > <TextView android:id="@+id/publicNumMenuTv1" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/menu_selector" android:gravity="center" android:padding="5dp" android:textColor="@color/the_color_black" android:textSize="@dimen/font_size_16sp" /> <View android:layout_width="1.0px" android:layout_height="match_parent" android:background="@color/layout_division_view" /> <TextView android:id="@+id/publicNumMenuTv2" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/menu_selector" android:gravity="center" android:padding="5dp" android:textColor="@color/the_color_black" android:textSize="@dimen/font_size_16sp" /> <View android:layout_width="1.0px" android:layout_height="match_parent" android:background="@color/layout_division_view" /> <TextView android:id="@+id/publicNumMenuTv3" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/menu_selector" android:gravity="center" android:padding="5dp" android:textColor="@color/the_color_black" android:textSize="@dimen/font_size_16sp" /> </LinearLayout> <LinearLayout android:id="@+id/kayboadFrame" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:gravity="bottom" > <ImageView android:id="@+id/audio_switch_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_margin="3dp" android:src="@drawable/talk_detail_audio_btn" /> <RelativeLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" > <LinearLayout android:id="@+id/edit_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_margin="2dp" > <RelativeLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <com.qyx.android.weight.edittext.EmojisEditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/edittext_bg" android:maxHeight="200dp" android:maxLines="4" android:minHeight="35dp" android:paddingBottom="3dp" android:paddingRight="35dp" android:textColor="@color/the_color_black" android:textColorHint="@color/the_color_black" android:textCursorDrawable="@drawable/color_cursor" android:textSize="@dimen/font_size_14sp" /> <ImageView android:id="@+id/action_show_emoji_panel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@id/editText" android:layout_alignRight="@id/editText" android:layout_marginBottom="5dp" android:src="@drawable/emoji" /> </RelativeLayout> <TextView android:id="@+id/send_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginBottom="2dp" android:layout_marginLeft="5dip" android:background="@color/the_color_blue" android:gravity="center" android:paddingBottom="6dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="6dp" android:text="@string/sent" android:textColor="@color/the_color_white" android:textSize="@dimen/font_size_14sp" android:visibility="gone" /> </LinearLayout> <Button android:id="@+id/sendAudio" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:background="@drawable/button_audio_bg" android:gravity="center" android:padding="6dp" android:text="@string/press_talk" android:textColor="@color/the_color_normal" android:textSize="@dimen/font_size_18sp" android:visibility="gone" /> </RelativeLayout> <ImageView android:id="@+id/addMoreBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginBottom="2dp" android:layout_marginLeft="10dp" android:layout_marginRight="5dp" android:src="@drawable/talk_detail_add_btn" /> </LinearLayout> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1.0px" android:background="@color/layout_division_view" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="1.0px" android:background="@color/layout_division_view" /> <RelativeLayout android:id="@+id/action_view" android:layout_width="match_parent" android:layout_height="240dp" android:background="@color/the_color_white" android:visibility="gone" > <LinearLayout android:id="@+id/emoji_action" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:visibility="gone" > <LinearLayout android:id="@+id/content_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/gif_list" android:layout_width="match_parent" android:layout_height="0dp" android:layout_gravity="center" android:layout_weight="1" /> <LinearLayout android:id="@+id/points_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginBottom="5dp" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/point" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <View android:id="@+id/view" android:layout_width="match_parent" android:layout_height="1.0px" android:background="@color/layout_division_view" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/emoji_add_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerInParent="true" android:paddingLeft="20dp" android:paddingRight="20dp" android:src="@drawable/icon_emoji_add" /> <ImageView android:id="@+id/emoji_setting_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerInParent="true" android:paddingLeft="20dp" android:paddingRight="20dp" android:src="@drawable/icon_emoji_setting" /> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview_horizontal" android:layout_width="match_parent" android:layout_height="35dp" android:layout_toLeftOf="@id/emoji_setting_iv" android:layout_toRightOf="@id/emoji_add_iv" android:scrollbars="none" /> </RelativeLayout> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/more_actions" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginTop="10dp" android:gravity="center" android:orientation="vertical" android:visibility="gone" > <android.support.v4.view.ViewPager android:id="@+id/more_list_viewpager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_gravity="center" android:layout_weight="1" /> <LinearLayout android:id="@+id/more_points_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginBottom="5dp" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/point" /> </LinearLayout> </LinearLayout> </RelativeLayout> </LinearLayout>
Activity布局页面引入面板布局:
<com.test.emoji.face.panel.ResizeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/messagelist" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/page_bg_normal" > <TextView android:id="@+id/gif_view" android:layout_width="100dp" android:layout_height="100dp" android:text="@string/hide_soft" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:gravity="center" android:background="@color/the_color_gray" android:textColor="@color/the_color_black" android:layout_marginBottom="50dp" android:visibility="visible" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/gif_view" android:orientation="vertical" > <ListView android:id="@+id/msg_listView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:cacheColorHint="@android:color/transparent" android:divider="@null" android:listSelector="@android:color/transparent" android:visibility="visible" /> <include android:id="@+id/face_panel" layout="@layout/face_panel_layout" /> </LinearLayout> </com.test.emoji.face.panel.ResizeLayout>
布局中ResizeLayout是用来计算软键盘高度的View,一下是ResizeLayout的源码:
public class ResizeLayout extends RelativeLayout { private OnResizeListener mListener; public interface OnResizeListener { void OnResize(int w, int h, int oldw, int oldh); } public void setOnResizeListener(OnResizeListener l) { mListener = l; } public ResizeLayout(Context context) { super(context); } public ResizeLayout(Context context, AttributeSet attrs) { super(context, attrs); } public ResizeLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (mListener != null) { mListener.OnResize(w, h, oldw, oldh); } } }
以上是布局文件。下面来看面板逻辑的实现。
以下这个类很重要,他主要实现了面板和软键盘的切换和软键盘的高度计算,以及面板中表情的显示和面板中控件的点击回调等。(程序猿组织语言能力欠佳,还是看源码吧)
public class FacePanelManager { /** * 计算软键盘高度 */ private ResizeLayout mResizeLayout; private ViewPager gif_list, moreViewPager; private RecyclerView listView; private BottomEmojiAdapter mBottomEmojiAdapter; private LinearLayout indexGroup, moreIndexGroup; private GifAdapter mAdapter = null; private EmojiAdapter emojiAdapter = null; private CheckEmojiEntity selectedCheckEmoji = null; private ArrayList<CheckEmojiEntity> arrayList = null; private boolean flag; private int keyboardHeight = 0; /*** * 底部布局 */ private View action_view; private InputMethodManager inputManager; private EditText sendEdit; /** * emojiBtn:表情按钮 ,addMoreBtn:更多按钮,audioBtn:语音按钮,publicNumSoft:公众号按钮 */ private ImageView emojiBtn, addMoreBtn, audioBtn, publicNumSoft; /** * 发送消息按钮 */ private TextView send; /** * 发送语音按钮 */ private Button sendAudioButton; /** * */ private LinearLayout editView; /** * 更多布局 */ private LinearLayout more_actions, emoji_action; /** * 公众号textview */ private TextView publicNumMenuTv1, publicNumMenuTv2, publicNumMenuTv3; private View public_num_view; /** * 公众号布局和输入框布局 */ private LinearLayout publicNumLayout, kayboadFrameLayout; private ISendAudioListener mSendAudioListener = null; private ISendTextListener mSendTextListener = null; private ISendGifListener mISendGifListener = null; private ISendHideFacePanel mISendHideFacePanel = null; private Context mContext; private PanelMoreManager mPanelMoreManager; private PanelPublicNumManager mPanelPublicNumManager; private boolean isShowPublicNumSoft = false; /** * 面板管理 * * @param _Context * @param view * 面板布局 * @param _recordView * 录音布局 * @param _ResizeLayout * 获取软键盘高度 * @param is_show_public_num_soft * 是否显示公众号软键盘 */ public FacePanelManager(Context _Context, View view, ResizeLayout _ResizeLayout, boolean is_show_public_num_soft) { isShowPublicNumSoft = is_show_public_num_soft; mResizeLayout = _ResizeLayout; mContext = _Context; initView(view); mPanelMoreManager = new PanelMoreManager(moreIndexGroup, moreViewPager, mContext); mPanelPublicNumManager = new PanelPublicNumManager(_Context, kayboadFrameLayout, publicNumLayout, publicNumSoft, public_num_view, publicNumMenuTv1, publicNumMenuTv2, publicNumMenuTv3, new ISendPublicNumOnClick() { @Override public void onPublicNumClick(String url) { Toast.makeText(mContext, url, Toast.LENGTH_SHORT) .show(); } }); } // 初始化控件 private void initView(View view) { inputManager = (InputMethodManager) mContext .getSystemService(Context.INPUT_METHOD_SERVICE); emojiBtn = (ImageView) view.findViewById(R.id.action_show_emoji_panel); action_view = view.findViewById(R.id.action_view); addMoreBtn = (ImageView) view.findViewById(R.id.addMoreBtn); audioBtn = (ImageView) view.findViewById(R.id.audio_switch_btn); gif_list = (ViewPager) view.findViewById(R.id.gif_list); moreViewPager = (ViewPager) view.findViewById(R.id.more_list_viewpager); indexGroup = (LinearLayout) view.findViewById(R.id.points_view); moreIndexGroup = (LinearLayout) view .findViewById(R.id.more_points_view); mResizeLayout.setOnResizeListener(resizeListener); sendEdit = (EditText) view.findViewById(R.id.editText); send = (TextView) view.findViewById(R.id.send_btn); more_actions = (LinearLayout) view.findViewById(R.id.more_actions); emoji_action = (LinearLayout) view.findViewById(R.id.emoji_action); editView = (LinearLayout) view.findViewById(R.id.edit_view); sendAudioButton = (Button) view .findViewById(R.id.sendAudio); /** * 公众号 */ publicNumSoft = (ImageView) view.findViewById(R.id.public_num_soft); publicNumMenuTv1 = (TextView) view.findViewById(R.id.publicNumMenuTv1); publicNumMenuTv2 = (TextView) view.findViewById(R.id.publicNumMenuTv2); publicNumMenuTv3 = (TextView) view.findViewById(R.id.publicNumMenuTv3); publicNumLayout = (LinearLayout) view .findViewById(R.id.publicNumLayout); kayboadFrameLayout = (LinearLayout) view .findViewById(R.id.kayboadFrame); public_num_view = view.findViewById(R.id.public_num_view); initHorizaontal(view); } public void initListener() { emojiBtn.setOnClickListener(clickListener); addMoreBtn.setOnClickListener(clickListener); /** 内容编辑框事件 **/ sendEdit.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showSoftKeyboard(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } sendEdit.setFocusable(true); sendEdit.setFocusableInTouchMode(true); sendEdit.requestFocus(); setActionViewDisplay(1); emojiBtn.setImageResource(R.drawable.emoji); } }); sendEdit.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (TextUtils.isEmpty(s) || TextUtils.isEmpty(sendEdit.getText().toString() .trim())) { send.setVisibility(View.GONE); addMoreBtn.setVisibility(View.VISIBLE); return; } if (count <= 0) { return; } /** 控制发送按钮和更多按钮的显示和隐藏 **/ if (sendEdit.getText().toString().trim().length() > 0) { send.setVisibility(View.VISIBLE); addMoreBtn.setVisibility(View.GONE); } else { send.setVisibility(View.GONE); addMoreBtn.setVisibility(View.VISIBLE); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }); send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String content = sendEdit.getText().toString(); if (mSendTextListener != null) { mSendTextListener.onSendTextContent(content); } sendEdit.setText(""); } }); /********* 语音按钮操作 ************/ audioBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { /** 隐藏编辑框、显示发送语音按钮 **/ if (sendAudioButton.getVisibility() == View.GONE) { editView.setVisibility(View.GONE); sendAudioButton.setVisibility(View.VISIBLE); audioBtn.setImageResource(R.drawable.talk_detail_keyboard_btn); hideSoftKeyboard(); // actionView.setVisibility(View.GONE); setActionViewDisplay(1); } else { /** 显示编辑框、隐藏发送语音按钮 **/ editView.setVisibility(View.VISIBLE); sendAudioButton.setVisibility(View.GONE); emojiBtn.setImageResource(R.drawable.emoji); audioBtn.setImageResource(R.drawable.talk_detail_audio_btn); sendEdit.setFocusable(true); sendEdit.setFocusableInTouchMode(true); sendEdit.requestFocus(); showSoftKeyboard(); } emojiBtn.setBackgroundResource(R.drawable.emoji); } }); /** 公众号和标签输入框切换 **/ publicNumSoft.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (kayboadFrameLayout.getVisibility() == View.VISIBLE) { // TODO kayboadFrameLayout.setVisibility(View.GONE); publicNumLayout.setVisibility(View.VISIBLE); publicNumSoft.setImageResource(R.drawable.icon_menu_top); } else { kayboadFrameLayout.setVisibility(View.VISIBLE); publicNumLayout.setVisibility(View.GONE); publicNumSoft.setImageResource(R.drawable.icon_menu_bottom); } sendEdit.setFocusable(true); sendEdit.setFocusableInTouchMode(true); sendEdit.requestFocus(); emojiBtn.setBackgroundResource(R.drawable.emoji); setActionViewDisplay(1); inputManager.hideSoftInputFromWindow(sendEdit.getWindowToken(), 0); } }); if (isShowPublicNumSoft) { publicNumSoft.setVisibility(View.VISIBLE); publicNumLayout.setVisibility(View.VISIBLE); } } private void initHorizaontal(View view) { listView = (RecyclerView) view .findViewById(R.id.recyclerview_horizontal); // 创建一个线性布局管理器 LinearLayoutManager layoutManager = new LinearLayoutManager(mContext); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); // 设置布局管理器 listView.setLayoutManager(layoutManager); getData(); } private void getData() { arrayList = new ArrayList<CheckEmojiEntity>(); CheckEmojiEntity mCheckEmojiEntity1 = new CheckEmojiEntity(1, R.drawable.ajmd_s_pressed, "ajmd"); CheckEmojiEntity mCheckEmojiEntity2 = new CheckEmojiEntity(2, R.drawable.icon_tusiji, "tusiji"); CheckEmojiEntity mCheckEmojiEntity3 = new CheckEmojiEntity(3, R.drawable.xxy_s_pressed, "hb"); CheckEmojiEntity mCheckEmojiEntity4 = new CheckEmojiEntity(4, R.drawable.xxy_s_pressed, "bu"); arrayList.add(mCheckEmojiEntity1); arrayList.add(mCheckEmojiEntity2); arrayList.add(mCheckEmojiEntity3); arrayList.add(mCheckEmojiEntity4); // 设置emoji表情在第一个 arrayList.add(0, new CheckEmojiEntity(-1, -1, "")); mBottomEmojiAdapter = new BottomEmojiAdapter(mContext, arrayList, new IOnItemClick() { @Override public void onItemClick(CheckEmojiEntity mCheckEmojiEntity) { if (mCheckEmojiEntity != null) { if (selectedCheckEmoji == mCheckEmojiEntity) { return; } else { selectedCheckEmoji = mCheckEmojiEntity; } flag = true; mBottomEmojiAdapter .setSelectedItem(mCheckEmojiEntity.id); if (mCheckEmojiEntity.id == -1 && mCheckEmojiEntity.resourceId == -1 && TextUtils .isEmpty(mCheckEmojiEntity.resourceName)) { showIndexMark(0, 1, mCheckEmojiEntity.resourceName); } else { showIndexMark(0, 2, mCheckEmojiEntity.resourceName); } } } }); listView.setAdapter(mBottomEmojiAdapter); // 设置默认值 showIndexMark(0, 1, ""); selectedCheckEmoji = arrayList.get(0); mBottomEmojiAdapter.setSelectedItem(selectedCheckEmoji.id); } /** * 表情按钮和更多按钮点击事件 */ private final View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { sendEdit.setFocusable(true); sendEdit.setFocusableInTouchMode(true); sendEdit.requestFocus(); if (v == emojiBtn) { if (action_view.getVisibility() == View.VISIBLE) { if (more_actions.getVisibility() == View.VISIBLE) { more_actions.setVisibility(View.GONE); emoji_action.setVisibility(View.VISIBLE); emojiBtn.setImageResource(R.drawable.ic_emoji_selector); return; } showSoftKeyboard(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } setActionViewDisplay(1); emojiBtn.setBackgroundResource(R.drawable.emoji); } else { hideSoftKeyboard(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } setActionViewDisplay(2); emoji_action.setVisibility(View.VISIBLE); emojiBtn.setImageResource(R.drawable.ic_emoji_selector); } } else if (v == addMoreBtn) { editView.setVisibility(View.VISIBLE); sendAudioButton.setVisibility(View.GONE); emoji_action.setVisibility(View.GONE); emojiBtn.setImageResource(R.drawable.emoji); audioBtn.setImageResource(R.drawable.talk_detail_audio_btn); if (action_view.getVisibility() == View.VISIBLE) { // 更多布局已经显示 if (more_actions.getVisibility() == View.VISIBLE) { showSoftKeyboard(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } setActionViewDisplay(1); more_actions.setVisibility(View.GONE); } else { // 更多布局未显示 hideSoftKeyboard(); more_actions.setVisibility(View.VISIBLE); emoji_action.setVisibility(View.GONE); } } else { hideSoftKeyboard(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } setActionViewDisplay(2); more_actions.setVisibility(View.VISIBLE); // showBottomView(1); // scrollToEnd(); } } } }; /** * 显示emoji或者gif标点 * * @param index * @param file_type_name */ private void showIndexMark(int index, int type, String file_type_name) { if (index == 0 && type == 2) { initViewPageData(file_type_name); } else if (index == 0 && type == 1) { initEmojiViewPageData(); } if (type == 2) { if (mAdapter == null) return; } else if (type == 1) { if (emojiAdapter == null) { return; } } int max = 0; if (type == 1) { max = emojiAdapter.getCount(); } else { max = mAdapter.getCount(); } indexGroup.removeAllViews(); for (int i = 0; i < max; i++) { ImageView image = new ImageView(mContext); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); lp.leftMargin = 10; lp.rightMargin = 10; lp.topMargin = 5; lp.bottomMargin = 5; if (index == i) { image.setImageResource(R.drawable.point_selected); } else { image.setImageResource(R.drawable.point); } image.setLayoutParams(lp); indexGroup.addView(image); } } /** * 初始化emoji事件 */ private void initEmojiViewPageData() { emojiAdapter = new EmojiAdapter(mContext, new OnEmojiSelected() { @Override public void onEmojiSelected(Emoji emoji) { if (TextUtils.isEmpty(emoji.text)) { return; } int index = sendEdit.getSelectionStart(); String text = sendEdit.getText().toString(); String startString = text.substring(0, index); String endString = text.substring(index, text.length()); String emojiText = "[" + emoji.text + "] "; sendEdit.setFocusable(true); sendEdit.setFocusableInTouchMode(true); sendEdit.requestFocus(); sendEdit.setText(startString + emojiText + endString); sendEdit.setSelection(index + emojiText.length()); } @Override public void onEmojiDeleted(Emoji emoji) { QyxEmoji.deleteEmoji(sendEdit, emoji.text); } }); gif_list.setAdapter(emojiAdapter); initViewPageLisenter(1, ""); } /** * 初始化viewpage数据 * * @param file_type_name * 显示表情的所在文件夹的目录 */ private void initViewPageData(final String file_type_name) { mAdapter = new GifAdapter(mContext, file_type_name, new OnBuildInViewGifSelected() { @Override public void onGifSelected(ViewGif mGif) { if (mISendGifListener != null) { mISendGifListener.onSendGif(mGif.file_type_name); } // gif_view.setAsyncCacheImage(mGif.file_type_name); } }); gif_list.setAdapter(mAdapter); initViewPageLisenter(2, file_type_name); } /** * 注册ViewPage滑动事件 * * @param type * 1:emoji2:gif * @param file_type_name * 1:“”2:gif类型名称 */ private void initViewPageLisenter(final int type, final String file_type_name) { gif_list.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int index) { showIndexMark(index, type, file_type_name); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { /** 设置viewpage滑动到最后一页和第一页的时切换其他类型Gif表情 **/ switch (arg0) { case ViewPager.SCROLL_STATE_DRAGGING: flag = false; break; case ViewPager.SCROLL_STATE_SETTLING: flag = true; break; case ViewPager.SCROLL_STATE_IDLE: if (gif_list.getCurrentItem() == gif_list.getAdapter() .getCount() - 1 && !flag) { showLastGif(); } else if (gif_list.getCurrentItem() == 0 && !flag) { showPreviousGif(); } flag = true; break; } } }); } /** * 显示下一个GifViewPage */ private void showLastGif() { if (selectedCheckEmoji != null && arrayList != null && arrayList.size() > 0) { for (int i = 0, size = arrayList.size(); i < size; i++) { if (selectedCheckEmoji == arrayList.get(i) && i < arrayList.size() - 1) { // 显示下一个GifViewPage int lastIndex = ++i; if (lastIndex >= arrayList.size()) { return; } /** 选中第一个item **/ showIndexMark(0, 2, arrayList.get(lastIndex).resourceName); /** 设置当前选中的gif类型 **/ selectedCheckEmoji = arrayList.get(lastIndex); /** 修改选中的表情背景 **/ mBottomEmojiAdapter.setSelectedItem(arrayList .get(lastIndex).id); listView.scrollToPosition(lastIndex); break; } } } } /** * 显示上个gifViewPage(默认选中上一个gif表情的最后一个item) */ private void showPreviousGif() { if (selectedCheckEmoji != null && arrayList != null && arrayList.size() > 0) { for (int i = 0, size = arrayList.size(); i < size; i++) { if (selectedCheckEmoji == arrayList.get(i) && i != 0) { // 显示上一个GifViewPage int previousIndex = --i; if (previousIndex >= arrayList.size() || previousIndex < 0) { return; } int type = 0; if (previousIndex == 0) { // 第一页 显示emoji表情 type = 1; } else { type = 2; } /** 选中最后一个item **/ showIndexMark(0, type, arrayList.get(previousIndex).resourceName); /** 选中最后一个item **/ if (gif_list != null) { int count = 0; if (previousIndex == 0) { // 第一页 显示emoji表情 count = emojiAdapter.getCount() - 1; } else { count = mAdapter.getCount() - 1; } gif_list.setCurrentItem(count); } /** 设置当前选中的gif类型 **/ selectedCheckEmoji = arrayList.get(previousIndex); /** 修改选中的表情背景 **/ mBottomEmojiAdapter.setSelectedItem(arrayList .get(previousIndex).id); listView.scrollToPosition(previousIndex); break; } } } } /** * 初始化更多数据 */ public void initMoreAdapter(ArrayList<MoreEntity> _ArrayList, IMoreOnClickListener mIMoreOnClickListener) { mPanelMoreManager.initMoreAdapter(_ArrayList, mIMoreOnClickListener); } /** * 设置底部view显示隐藏状态 * * @param type */ private void setActionViewDisplay(int type) { if (action_view != null) { if (type == 1) { action_view.setVisibility(View.GONE); more_actions.setVisibility(View.GONE); emoji_action.setVisibility(View.GONE); emojiBtn.setImageResource(R.drawable.emoji); } else { action_view.setVisibility(View.VISIBLE); } } } private void showSoftKeyboard() { ((Activity) mContext).getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); inputManager .showSoftInput(sendEdit, InputMethodManager.HIDE_NOT_ALWAYS); } private void hideSoftKeyboard() { ((Activity) mContext).getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); if (inputManager.isActive()) { inputManager.hideSoftInputFromWindow(sendEdit.getWindowToken(), 0); } } /** * 控制软键盘高度 */ private ResizeLayout.OnResizeListener resizeListener = new ResizeLayout.OnResizeListener() { @Override public void OnResize(int w, int h, int oldw, int oldh) { if (oldw != 0 && oldh != 0) { if (h < oldh) { keyboardHeight = oldh - h; keyboardHeight = Math.max(dip2px(mContext, 240), keyboardHeight); setFaceActionViewHeight(); } } } }; /** * 设置面板高度 * * @param keyboardHeight */ private void setFaceActionViewHeight() { LayoutParams faceParams = action_view.getLayoutParams(); faceParams.height = keyboardHeight; action_view.setLayoutParams(faceParams); } /** * 把dip值转换成px值 */ private int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } public void hideFacePanel() { } /** * 监听录音返回 * * @param _SendAudioListener */ public void onSendAudioListener(ISendAudioListener _SendAudioListener) { mSendAudioListener = _SendAudioListener; } /** * 发送按钮监听 * * @param _SendTextListener */ public void onSendTextListener(ISendTextListener _SendTextListener) { mSendTextListener = _SendTextListener; } /** * 发送gif监听 * * @param _SendGifListener */ public void onSendGifListener(ISendGifListener _SendGifListener) { mISendGifListener = _SendGifListener; } /** * 设置不显示面板 * * @param _HideFacePanel */ public void onSendHideFacePanel(ISendHideFacePanel _HideFacePanel) { mISendHideFacePanel = _HideFacePanel; mISendHideFacePanel.onHideFacePanel(new IHideFacePanel() { @Override public void hideFacePanel() { hideSoftKeyboard(); setActionViewDisplay(1); } }); } /** * 设置公众号数据 * * @param arrayList */ public void setPublicNumData(ArrayList<PublicNumMenu> arrayList) { if (isShowPublicNumSoft) { mPanelPublicNumManager.setPublicNumMenu(arrayList); } } }
以上就是面板的主要实现了。。。接下来就是如何调用这个面板啦!其实很简单。只需传入面板的布局和是否控制公众号键盘的显示和公众号数据。其他的事件点击会回调给Activity(面板中只处理了一些事件的回调。)一下是调用面板:
public class MainActivity extends Activity { private ResizeLayout mResizeLayout; private IHideFacePanel hideFacePanel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mResizeLayout = (ResizeLayout) findViewById(R.id.messagelist); initFacePanelView(); findViewById(R.id.gif_view).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { hideFacePanel.hideFacePanel(); } }); } /** * 模拟公众号数据 * @return */ private ArrayList<PublicNumMenu> getPublicNumData() { ArrayList<PublicNumMenu> arrayList = new ArrayList<PublicNumMenu>(); PublicNumMenu menu = new PublicNumMenu(); menu.text = "第一个"; menu.url = "http://www.baidu.com"; PublicNumMenu menu2 = new PublicNumMenu(); menu2.text = "第二个"; menu2.url = "http://www.baidu.com"; menu2.arrayList = getPublicNumData1(); PublicNumMenu menu3 = new PublicNumMenu(); menu3.text = "第三个"; menu3.url = "http://www.baidu.com"; arrayList.add(menu); arrayList.add(menu2); arrayList.add(menu3); return arrayList; } private ArrayList<PublicNumMenu> getPublicNumData1() { ArrayList<PublicNumMenu> arrayList = new ArrayList<PublicNumMenu>(); PublicNumMenu menu = new PublicNumMenu(); menu.text = "第一个"; menu.url = "http://www.baidu.com"; PublicNumMenu menu2 = new PublicNumMenu(); menu2.text = "第二个回火是"; menu2.url = "http://www.baidu.com"; PublicNumMenu menu3 = new PublicNumMenu(); menu3.text = "第三个"; menu3.url = "http://www.baidu.com"; arrayList.add(menu); arrayList.add(menu2); arrayList.add(menu3); return arrayList; } private void initFacePanelView() { View view = findViewById(R.id.face_panel); /**最后一个参数是控制是否显示公众号键盘**/ FacePanelManager facePanelManager = new FacePanelManager(this, view, mResizeLayout, false); facePanelManager.initListener(); facePanelManager.setPublicNumData(getPublicNumData()); /**点击加号的时候回调**/ facePanelManager.initMoreAdapter(PanelMoreManager.getPanelMoreData(2), new IMoreOnClickListener() { @Override public void onMoreClick(int type) { // TODO Toast.makeText(MainActivity.this, "更多模块item的点击" + type, Toast.LENGTH_SHORT).show(); } }); facePanelManager.onSendAudioListener(new ISendAudioListener() { @Override public void onAudioFilePath(String audioPath) { Toast.makeText(MainActivity.this, "发送语音" + audioPath, Toast.LENGTH_SHORT).show(); } }); facePanelManager.onSendGifListener(new ISendGifListener() { @Override public void onSendGif(String gifName) { Toast.makeText(MainActivity.this, "点击了某个gif表情:" + gifName, Toast.LENGTH_SHORT).show(); } }); facePanelManager.onSendTextListener(new ISendTextListener() { @Override public void onSendTextContent(String editContent) { Toast.makeText(MainActivity.this, "点击了发送按钮" + editContent, Toast.LENGTH_SHORT).show(); } }); facePanelManager.onSendHideFacePanel(new ISendHideFacePanel() { @Override public void onHideFacePanel(IHideFacePanel mHideFacePanel) { //通知面板、隐藏软键盘和面板 hideFacePanel = mHideFacePanel; } }); } }
好了。。。就写在这里吧!大家有啥不明白的直接问我吧!(Q:2473471081)
源码地址:http://download.csdn.net/detail/songneng1993/9490995
时间: 2024-10-07 17:24:02