IM即時通訊專案講解(一)--實現類似qq微信表情皮膚無縫切換
標籤(空格分隔): 開源專案
###該系列技術課程來源慕課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(這個裡面就需要用到庫中的自定的一個控制元件了)關於控制元件的使用在後面會進行相關講解,這個地方想說明如何引入到專案中
<?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的佈局裡面
<!--注意一點,根佈局使用的是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。這個就在於大家的取捨了。
###寫在最後 關於這個庫的介紹就不寫了,大致看了下,也是對於一個鍵盤的初始化,給一個最高和最低的值
<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高仿微信表情輸入與鍵盤輸入詳解