啥也不多说,先上图
先说实现的功能: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