首先:微信聊天功能模块包括
1,发送文字
2,发送表情
3,发送语音
4,发送图片(图库和相机,可以同时发送多张)
其中,文字和表情是可以一起发送的,可以同时存在同一个输入框当中,语音和图片是独立各自发送。
实现:文字和表情同时存在一个Edittext当中,可以同时发送。
使用自定义输入View控件。
实现之后的截图是酱的。
所以东西比较多,我们把他们统一放到我们的自定义控件当中,切换通过Visibility来控制,然后表情,主要是通过ViewPager实现,ViePager里面使用的是一个GridView,GridView里面再去显示一个表情。然后得出我们的关键类:
FaceRelativeLayout,主要去初始化表情,管理表情。
表情转换Util:FaceConversionUtil,用于转换表情,读取表情,解释表情。主要使用到正则表达式去解释,然后SpannableString和ImageSpan去实现String转换为图片。
录音实现:使用一个自定义的Button,处理他自己的点击事件,通过回调回传数据给Activity,使用一个manager管理录音,比如开始,暂停,完成,取消等,使用一个Dialog实现录音情况显示,比如音量大小等。所以需要三个类
AudioRecoderButton 自定义button,处理自己的onTouch事件,从而处理录音情况,比如超出范围取消,范围内发送等
AudoManager 处理,音频文件保存,开始,释放
DialogManager 处理录音时候提示Dialog的显示,消失
播放,在用户点击播放声音的时候播放,是在ListView的item的对应的ImageView当中播放。使用一个manager管理
MediaManager 包括播放,错误处理,成功回调,暂停,释放
发送图片实现:首先是自定义一个图库,显示系统的所有照片,就是 ShowAllLocalPicActivity,然后需要显示某一个文件夹下面的全部照片ShowLocalDetailPicActivity,然后是点击单张照片的时候显示图片详情ShowOnePicActivity,可以切换。
所以有三个类
ShowAllLocalPicActivity 需要适配器,使用ListView,功能是显示所有照片,然后返回被选中的照片到MainActivity,然后发送。
ShowLocalDetailPicActivity需要适配器,使用GridView 可以选择或者取消被选中的照片
ShowOnePicActivity 需要适配器,使用ViewPager实现 可以选择或者取消被选中的照片
然后到我们的MainActivity,他也是需要适配器,使用ListView显示聊天内容、
聊天内容划分:
首先是否是自己发送的,然后是哪一类,包括文字表情,语音,图片,三类。
难点在View的重用上面
,我们需要在适配器的getView方法中,进行判断,逻辑是:
先是是否自己发送的,然后是这个converView是否为null和不为null,他是属于谁的,加入converview为null或者converview不属于对应的人,那么,我们就需要重写生成converview。否则,重用就好。
然后,通过判断他的type,看他属于哪一类的消息,就使用哪一类的控件显示。
还有,输入法的问题
强制隐藏或者是显示输入法:
public class InputMethodUtil {
//其中et_sendmessage是需要输入的view,下面同是
public static void hideInput(Context context, EditText et_sendmessage) {
((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(et_sendmessage.getWindowToken(), 0); //制隐藏键盘
}
public static void showInput(Context context, EditText et_sendmessage) { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(et_sendmessage, InputMethodManager.SHOW_FORCED); }
}
监听输入法的打开或者是隐藏事件,使用你需要监听的Activity的根view,设置对应事件:
//键盘事件监听
final int heigh = getWindowManager().getDefaultDisplay().getHeight() /3; root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
//弹起事件
if (bottom != 0 && oldBottom != 0 && oldBottom- bottom >heigh) {
if (mListView.getLastVisiblePosition() != mDateArrays.size() - 1) {
mListView.smoothScrollToPosition(mDateArrays.size() -1);
}
}
else if(oldBottom != 0 && bottom != 0 &&(bottom - oldBottom > keyHeight)){
Toast.makeText(MainActivity.this, "监听到软件盘关闭...", Toast.LENGTH_SHORT).show(); }
}
});
需要在对应的Activity当中,设置
android :windowSoftInputMode= "stateAlwaysHidden|adjustResize"
即可监听。