IM即时通讯项目讲解(一)--实现类似qq微信表情面板无缝切换
2017-07-11 15:44
489 查看
该系列技术课程来源慕课IM实战
带后台的IM即时通讯App 全程MVP手把手打造通过该课程可以学习到以下知识点
1、了解和开发后台项目(这个是需要长期积累的,有了这个可以说入门没问题)
2、学习到IM相关知识点,创建群、添加群、单聊、群聊
3、可以学习到数据库的相关操作(建表、表之间的关联等知识)
4、学习到MVP模式,更加深入了解MVP模式的架构和实现
5、学习到关于IM相关的优化,比如如何快速刷新界面
6、学习到如何进行推送等相关操作(服务器端推送,单推、群推)
7。。。当然还有好多的,大家不妨去了解一下,学习到知识才是最重要的
首先看下效果图(无图耍流氓)
前言
这里首先给个完整的项目地址,该项目是一个完整的IM即时通信。涵盖的功能群聊、单聊、创建群组、添加好友等。。。。大家可以下载看下.相关功能点readme.md中都有简介。这个项目也算是一个完整的项目,并且运用了一些比较不错的知识点,还有就是项目中的一些小功能。在我们以后的开发或者写的项目中可能会有启发和用途,因此在这里通过写文章记录一下,一方面也是对于所学知识的巩固(正所谓码了也不一定会、会了也不一定总结出来、总结出来也不一定讲出来),正是这个道理,因为总结出来和自己会不是一个境界,能讲出来境界又是提高一层。所以大家不要只停留在码代码的一层,要做一名有追求的程序员(虽然我自己在码代码的道路上越走越远,但是始终不会放弃初心。加油—小菜鸟)
好了,说了那么多话,没一句说道本篇文章上,不过还要在说几句,关于这个IM即时通讯demo,我还是会写几篇文章对其进行总结的,也算是对于自己所学的一个考评吧。接下来会一到两周更新一篇。准备利用两个月时间消化吸收。
此篇文章背景
在自己的项目中,用到了EditText输入框,这个是之前已经开发好的,但是有一个问题,那就是没有解决相应的网络出现的各种冲突(泪奔),然后在自己开发社区的时候,在社区详情,对于评论过多的时候在弹出软键盘的时候(当再次点击取消软键盘消失的时候)下面的评论会进行跳动(也就是说取消之后定位的地方不是刚开始弹出软键盘的地方),当然这个和项目初期的控件,评论机制有关系,现在评论做成了本地评论(有相关的需求的可以进行讨论哈),现在问题解决了,但是还有个体验不好的地方就是软键盘的切换闪屏问题,就是当切换表情的时候屏幕会跳动,因此这个也是之后进行的版本优化任务。现在在这个项目中解决了软键盘的切换问题,基本达到了类似微信、QQ软键盘表情切换效果,让你体验如丝般顺畅。好了,有如此好的方法能够解决软键盘、表情切换方法或者代码,那还不赶紧给大家推荐推荐,以方便广大老铁们的开发哈。好了废话不多说。看看怎么集成到项目中吧。项目集成
原项目地址 Airpanel第一步
在module的build.gradle中加入(这个库很小,8个类,最大类也就200来行代码,小类几十行代码)compile 'net.qiujuer.widget:airpanel:1.0.0'
第二步
创建空气面板布局lay_chat_air_panel.xml(这个里面就需要用到库中的自定的一个控件了)关于控件的使用在后面会进行相关讲解,这个地方想说明如何引入到项目中AirPanelLinearLayout" data-snippet-id="ext.fabd47d36473988fc31c1b3261c1bc08" data-snippet-saved="false" data-codota-status="done">[code]<?xml version="1.0" encoding="utf-8"?> <net.qiujuer.widget.airpanel.AirPanelLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/airPanelSubLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="1px" android:visibility="gone"> <!--airPanelSubLayout这个根布局的id必须是这个--> <!--这里放入一个fragment,在这个fragment里面实现表情、语音、图片、输入法的相关逻辑切换--> <fragment android:id="@+id/frag_panel" class="com.mingchu.cnim4android.fragment.panel.PanelFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:layout="@layout/fragment_panel" /> </net.qiujuer.widget.airpanel.>AirPanelLinearLayout
这里给出这个fragment的相关逻辑实现(当然这个逻辑和软键盘没有任何关系了,只是负责控制哪个面板的显示和隐藏,因为所有的关于软键盘的控制都已经被AirPanelLinearLayout完成了)
public class PanelFragment extends BaseFragment implements FaceListener { //表情面板 private View mFacePanel; //图片相册面板 private View mGalleryPanel; //录音面板 private View mRecordPanel; private PanelCallback mCallback; public PanelFragment() { // Required empty public constructor } @Override protected int getContentLayoutId() { return R.layout.fragment_panel; } @Override protected void initView(View view) { super.initView(view); initRecord(view); initFace(view); initGallery(view); } //初始化表情布局 private void initFace(View root) { View facePanel = mFacePanel = root.findViewById(R.id.lay_face_panel); //todo 接下来就是相关的表情加载和相关点击的实现 这个有空就为大家在以后的文章中讲解 // } /** * 初始化录音布局 * * @param root 根布局 */ private void initRecord(View root) { View recordPanel = mRecordPanel = root.findViewById(R.id.lay_record_panel); //todo 接下来就是相关的语音录制相关点击的实现 这个有空就为大家在以后的文章中讲解 } /** * 初始化图片画廊 * * @param root 根布局 */ private void initGallery(View root) { View galleryPanel = mGalleryPanel = root.findViewById(R.id.lay_gallery_panel); //todo 接下来就是相关的图片展示和相关点击的实现 这个有空就为大家在以后的文章中讲解 } /** * 发送 * * @param galleryView * @param paths */ private void onSendGalleryClick(GalleryView galleryView, String[] paths) { galleryView.clear(); PanelCallback callback = mCallback; if (callback == null) return; callback.onSendGalleryClick(paths); } public void setup(PanelCallback callback) { this.mCallback = callback; } public boolean isOpenFace() { return mFacePanel.getVisibility() == View.VISIBLE; } public boolean isOpenMore() { return mGalleryPanel.getVisibility() == View.VISIBLE; } /** * 显示表情界面 */ public void showFace() { mFacePanel.setVisibility(View.VISIBLE); mGalleryPanel.setVisibility(View.GONE); mRecordPanel.setVisibility(View.GONE); } /** * 显示录音界面 */ public void showRecord() { mFacePanel.setVisibility(View.GONE); mGalleryPanel.setVisibility(View.GONE); mRecordPanel.setVisibility(View.VISIBLE); } /** * 显示图片界面 */ public void showGallery() { mFacePanel.setVisibility(View.GONE); mGalleryPanel.setVisibility(View.VISIBLE); mRecordPanel.setVisibility(View.GONE); GalleryView view = (GalleryView) mGalleryPanel.findViewById(R.id.view_gallery); view.clear(); } public void showMore() { showGallery(); } /** * 面板变化和相关输入输出的回调 */ public interface PanelCallback { //获取到输入的EditText的值 EditText getInputEditText(); /** * 点击发送按钮的时候发送图片地址集合 * * @param paths 本地相册图片路径 */ void onSendGalleryClick(String[] paths); /** * 录音完成的时候回调 * * @param file 录音文件 * @param time 录音时长 */ void onRecordDone(File file, long time); } }
这个时候万事俱备,只差我们怎么使用了,不急,一步一步来吗,毕竟心急吃不了热豆腐。刚才创建的那个布局,我们放到我们需要使用的fragment或者activity的布局里面
" data-snippet-id="ext.b2d6f661f07ed43af3802c1fd87f2d98" data-snippet-saved="false" data-codota-status="done">[code]<!--注意一点,根布局使用的是AirPanelLinearLayout--> <include layout="@layout/lay_chat_sub_air_panel"/>
好了,看下如何在fragment编写相关逻辑吧,当然我这里使用的是fragment,activity里面使用的逻辑也是一样的。
//第一步 //刚才我们实现的面板fragment private PanelFragment mPanelContent; //接口 private AirPanel.Boss mPanelBoss; //第二步 mPanelBoss = (AirPanel.Boss) view.findViewById(R.id.lay_container); //这个id就是根布局的id (也就是AirPanelLinearLayout或者是子类的id) mPanelBoss.setPanelListener(new AirPanel.Listener() { @Override public void requestHideSoftKeyboard() { // 这里面传递的是EditText控件 也就是我们的输入控件 Util这个方法是集成的库中的工具类 Util.hideKeyboard(mEtContent); } }); //第三步 找到我们的fragment 可以操作里面的控制逻辑 PanelFragment fragment = (PanelFragment) getChildFragmentManager().findFragmentById(R.id.frag_panel); //让我们的fragment实现这个方法PanelCallback fragment.setup(this); mPanelContent = fragment; //这个时候我们可以操作了 因为实现了PanelCallback这个接口,那么会实现里面的方法,我们看下如何处理吧 @Override public EditText getInputEditText() { //获取表情输入 当然需要自己进行转换 return mEtContent; } @Override public void onSendGalleryClick(String[] paths) { //图片地址 这个时候我们需要进行上传逻辑 mPresenter.pushImages(paths); } @Override public void onRecordDone(File file, long time) { //语音的发起 mPresenter.pushAudio(file.getAbsolutePath(), time); }
什么,这TM(提莫必须死)说的啥啊,瓜子毛嗑都准备好了,就给看这个。。。所有的点击事件怎么没有呢,不要急吗,先看一个图片
然后我们看下点击逻辑吧
//语音切换 @OnClick(R.id.btn_record) void onRecordClick() { if (mPanelBoss.isOpen()) { Util.showKeyboard(mEtContent); } else { mPanelContent.showRecord(); mPanelBoss.openPanel(); } } //图片点击 private void onMoreClick() { if (mPanelBoss.isOpen() && mPanelContent.isOpenMore()) { Util.showKeyboard(mEtContent); } else { mPanelContent.showMore(); mPanelBoss.openPanel(); } } //表情点击 @OnClick(R.id.btn_face) void onFaceClick() { if (mPanelBoss.isOpen() && mPanelContent.isOpenFace()) { //显示输入法 Util.showKeyboard(mEtContent); } else { mPanelContent.showFace(); mPanelBoss.openPanel(); } }
好了,这个时候就已经完美的实现了表情、输入法、语音、图片面板的切换了,是不是很简单哈。之前也看过好多的关于介绍输入法、表情切换闪屏问题,但是不知道是不是介绍的不详细还是实现比较困难(自己太菜),然后发现了这样的一个封装比较好的一个库,不过有个问题就是父布局必须是AirPanelLinearLayout。这个就在于大家的取舍了。
写在最后
关于这个库的介绍就不写了,大致看了下,也是对于一个键盘的初始化,给一个最高和最低的值280dp 86dp " data-snippet-id="ext.4e7e430936065d5d9ea299a52426c2fb" data-snippet-saved="false" data-codota-status="done">[code] <declare-styleable name="AirPanelLinearLayout"><attr format="dimension" name="airPanelMinHeight"/><attr format="dimension" name="airPanelMaxHeight"/></declare-styleable> <dimen name="airPanelMaxHeight">280dp</dimen> <dimen name="airPanelMinHeight">86dp</dimen> <item name="airPanelSubLayout" type="id"/>
然后在Helper这个类中进行拿到这些属性,并进行相应的逻辑,比如里面的计算软键盘高度、修复高度、设置相关监听、检测软键盘的动作等逻辑,大家看下也就明白了。
参考文章
解决Android软键盘和表情面板切换界面闪动问题Android键盘面板冲突 布局闪动处理方案
Android高仿微信表情输入与键盘输入详解
相关文章推荐
- Android: 实现类似QQ、微信的表情输入键盘
- Android: 实现类似QQ、微信的表情输入键盘
- Android 实现微信,QQ的程序前后台切换:back键切换后台;点击通知栏恢复前台。
- android 实现类似qq表情
- Android 实现微信,QQ的程序前后台切换:back键切换后台;点击通知栏恢复前台。
- iOS 类似微信,QQ聊天界面的气泡聊天简单实现Demo
- 实现类似QQ聊天列表的segment点击切换tableView的数据功能
- 使用ViewPager实现几个界面的切换,类似QQ
- Android能否实现一键清理后台程序后程序自启动(类似QQ微信不被清理软件杀死)
- android 实现类似微信滑动切换界面
- Android应用中使用ViewPager实现类似QQ的界面切换效果
- IOS 实现边滑动边缩放的类似qq主界面的页面切换功能
- 用DELPHI、RxRichEdit控件实现类似QQ的表情输入方法
- ListView 实现IM 类似QQ 微信 item置顶最简单的方法
- richTextBox如何实现输入指定的字符显示一个表情图标?类似QQ那样?
- 深层切换效果实现原理的理解(类似微信)
- js实现类似qq表情(插入图片以及获取光标的效果)
- Android实现程序前后台切换效果(类似QQ后台运行)
- Android实现微信、QQ的程序前后台切换
- ShareSDK 实现新浪微博分享(微信,QQ,新浪微博类似)