Android鍵盤皮膚衝突 佈局閃動處理方案
起源,之前在微信工作的時候,為了給使用者帶來更好的基礎體驗,做了很多嘗試,踩了很多輸入法的坑,特別是動態調整鍵盤高度,二級頁面是透明背景,魅族早期的Smart bar等, 後來逐一完善了,考慮到擁抱開源,看業界還是有很多應用存在類似問題。就有了這個repo
之前有寫過一篇核心思想: Switching between the panel and the keyboard in Wechat。
歡迎提交 Pull requests
- 儘量多的英文註解。
- 每個提交儘量的細而精準。
- Commit message 遵循: AngularJS's commit message convention。
- 儘可能的遵循IDE的程式碼檢查建議(如 Android Studio 的 'Inspect Code')。
如何使用
在build.gradle
中引入:
compile 'cn.dreamtobe.kpswitch:library:1.4.4'
使用引導
非全屏主題情況下使用引導
所謂非全屏主題,就是
(activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0
I. AndroidManifest
可直接參照: AndroidManifest.xml
對應的Activity,在
AndroidManifest
中配置android:windowSoftInputMode=adjustResize
<manifest
...>
<application
...>
<activity
android:name=".activity.ChattingActivity"
android:windowSoftInputMode=adjustResize"/>
...
</application>
...
</manifest>
II. 需要處理頁面的layout xml
- 需要用到 最上層佈局 (KPSwitchRootFrameLayout/KPSwitchRootLinearLayout/KPSwitchRootRelativeLayout)
- 需要用到 皮膚佈局(KPSwitchPanelFrameLayout/KPSwitchPanelLinearLayout/KPSwitchPanelRelativeLayout)。
簡單案例:
<?xml version="1.0" encoding="utf-8"?>
<!-- 可選用 KPSwitchRootLinearLayout、KPSwitchRootRelativeLayout、KPSwitchRootFrameLayout -->
<cn.dreamtobe.kpswitch.widget.KPSwitchRootLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 佈局內容 -->
...
<!-- 可選用 KPSwitchPanelLinearLayout、KPSwitchPanelRelativeLayout、KPSwitchPanelFrameLayout -->
<cn.dreamtobe.kpswitch.widget.KPSwitchPanelLinearLayout
android:id="@+id/panel_root"
android:layout_width="fill_parent"
android:layout_height="@dimen/panel_height"
android:visibility="gone">
<!-- 皮膚內容 -->
...
</cn.dreamtobe.kpswitch.widget.KPSwitchPanelLinearLayout>
</cn.dreamtobe.kpswitch.widget.KPSwitchRootLinearLayout>
III. 需要處理頁面的Activity:
- 處理一些事件(KPSwitchConflictUtil)
- 鍵盤狀態(高度與顯示與否)監聽(KeyboardUtil#attach())
簡單案例:
...
// 皮膚View
private KPSwitchPanelLinearLayout mPanelLayout;
// 鍵盤焦點View,用於輸入內容
private EditText mSendEdt;
// 用於切換鍵盤與皮膚的按鈕View
private ImageView mPlusIv;
@Override
public void onCreate(Bundle saveInstanceState){
...
mPanelLayout = (KPSwitchPanelLinearLayout)findViewById(R.id.panel_root);
mSendEdt = (EditText) findViewById(R.id.send_edt);
mPlusIv = (ImageView) findViewById(R.id.plus_iv);
/**
* 這個Util主要是監控鍵盤的狀態: 顯示與否 以及 鍵盤的高度
* 這裡也有提供給外界監聽 鍵盤顯示/隱藏 的監聽器,具體參看
* 這個介面 {@Link KeyboardUtil#attach(Activity, IPanelHeightTarget, OnKeyboardShowingListener)}
*/
KeyboardUtil.attach(this, mPanelLayout);
/**
* 這個Util主要是協助處理一些皮膚與鍵盤相關的事件。
* 這個方法主要是對一些相關事件進行註冊,如切換皮膚與鍵盤等,具體參看原始碼,比較簡單。
* 裡面還提供了一些已經處理了衝突的工具方法: 顯示皮膚;顯示鍵盤;鍵盤皮膚切換;隱藏鍵盤與皮膚;
*
* @param panelRoot 皮膚的佈局。
* @param switchPanelKeyboardBtn 用於觸發切換皮膚與鍵盤的按鈕。
* @param focusView 鍵盤彈起時會給這個View focus,收回時這個View會失去focus,通常是傳送的EditText。
*/
KPSwitchConflictUtil.attach(mPanelLayout, mPlusIv, mSendEdt);
}
...
...
// 如果需要處理返回收起皮膚的話
@Override
public boolean dispatchKeyEvent(KeyEvent event){
if (event.getAction() == KeyEvent.ACTION_UP &&
event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (mPanelLayout.getVisibility() == View.VISIBLE) {
KPSwitchConflictUtil.hidePanelAndKeyboard(mPanelLayout);
return true;
}
}
return super.dispatchKeyEvent(event);
}
全屏主題情況下使用引導
所謂全屏主題,就是
(activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
I. AndroidManifest
可直接參照: AndroidManifest.xml
對應的Activity,在
AndroidManifest
中配置android:windowSoftInputMode=adjustUnspecified
,或者不配置,預設就是這個模式。
II. 需要處理頁面的layout xml
可直接參照: activity_chatting_fullscreen_resolved.xml
這邊只需要用到一個 皮膚佈局(KPSwitchFSPanelFrameLayout/KPSwitchFSPanelLinearLayout/KPSwitchFSPanelRelativeLayout)
<?xml version="1.0" encoding="utf-8"?>
...
...
<!-- 可選用 KPSwitchFSPanelFrameLayout、KPSwitchFSPanelLinearLayout、KPSwitchFSPanelRelativeLayout -->
<cn.dreamtobe.kpswitch.widget.KPSwitchFSPanelFrameLayout
android:id="@+id/panel_root"
style="@style/Panel"
android:visibility="gone">
...
</cn.dreamtobe.kpswitch.widget.KPSwitchFSPanelFrameLayout>
...
III. 需要處理頁面的Activity:
- 主要是處理一些事件(KPSwitchConflictUtil)
- 鍵盤狀態(高度與顯示與否)監聽(KeyboardUtil#attach())
- 在
onPause
時,記錄鍵盤狀態用於從後臺回到當前佈局,恢復鍵盤狀態不至於衝突(IFSPanelConflictLayout#recordKeyboardStatus())
如下使用案例:
...
// 皮膚View
private KPSwitchFSPanelLinearLayout mPanelLayout;
// 鍵盤焦點View,用於輸入內容
private EditText mSendEdt;
// 用於切換鍵盤與皮膚的按鈕View
private ImageView mPlusIv;
@Override
public void onCreate(Bundle saveInstanceState){
...
mPanelLayout = (KPSwitchFSPanelLinearLayout)findViewById(R.id.panel_root);
mSendEdt = (EditText) findViewById(R.id.send_edt);
mPlusIv = (ImageView) findViewById(R.id.plus_iv);
/**
* 這個Util主要是監控鍵盤的狀態: 顯示與否 以及 鍵盤的高度
* 這裡也有提供給外界監聽 鍵盤顯示/隱藏 的監聽器,具體參看
* 這個介面 {@Link KeyboardUtil#attach(Activity, IPanelHeightTarget, OnKeyboardShowingListener)}
*/
KeyboardUtil.attach(this, mPanelLayout);
/**
* 這個Util主要是協助處理一些皮膚與鍵盤相關的事件。
* 這個方法主要是對一些相關事件進行註冊,如切換皮膚與鍵盤等,具體參看原始碼,比較簡單。
* 裡面還提供了一些已經處理了衝突的工具方法: 顯示皮膚;顯示鍵盤;鍵盤皮膚切換;隱藏鍵盤與皮膚;
*
* @param panelRoot 皮膚的佈局。
* @param switchPanelKeyboardBtn 用於觸發切換皮膚與鍵盤的按鈕。
* @param focusView 鍵盤彈起時會給這個View focus,收回時這個View會失去focus,通常是傳送的EditText。
*/
KPSwitchConflictUtil.attach(mPanelLayout, mPlusIv, mSendEdt);
}
@Override
protected void onPause() {
super.onPause();
// 用於記錄當前的鍵盤狀態,在從後臺回到當前頁面的時候,鍵盤狀態能夠正確的恢復並且不會導致佈局衝突。
mPanelLayout.recordKeyboardStatus(getWindow());
}
...
// 如果需要處理返回收起皮膚的話
@Override
public boolean dispatchKeyEvent(KeyEvent event){
if (event.getAction() == KeyEvent.ACTION_UP &&
event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (mPanelLayout.getVisibility() == View.VISIBLE) {
KPSwitchConflictUtil.hidePanelAndKeyboard(mPanelLayout);
return true;
}
}
return super.dispatchKeyEvent(event);
}
基本原理
- 鍵盤高度計算,以及鍵盤是否顯示的計算,參看:KeyboardUtil.KeyboardStatusListener#calculateKeyboardHeight、KeyboardUtil.KeyboardStatusListener#calculateKeyboardShowing。
- 處理閃動問題,參看: KPSwitchRootLayoutHandler,以及如果是非全屏主題用到的皮膚佈局:KPSwitchPanelLayoutHandler;如果是全屏主題用到的皮膚佈局: KPSwitchFSPanelLayoutHandler。
擴充套件閱讀
Android Studio 提示與技巧(官方文件翻譯)Android中軟鍵盤彈出時關於佈局的問題
android軟鍵盤彈出引起的各種不適終極解決方案
介紹 Visual Studio 的 Android 模擬器
JavaScript 資源大全中文版
為您推薦
hadoop分散式叢集搭建功能強大的驗證碼的Java類庫:Patchca
CAS實現SSO(單點登入)
Struts2 json plugin實戰2
Webpack + React 開發之路
更多
Android鍵盤
Android開發
專案描述:For resolve the layout conflict when keybord & panel are switching (Android鍵盤皮膚衝突 佈局閃動處理方案) — 檢視更多內容..
相關文章
- Android 解決表情皮膚和軟鍵盤切換時跳閃的問題Android
- 處理併發衝突
- Android事件傳遞、多點觸控及滑動衝突的處理Android事件
- 每日一問:Android 滑動衝突,你們都是怎樣處理的Android
- Maven依賴衝突處理Maven
- 《部落衝突》春節限定皮膚揭曉 首款中國風皮膚木蘭登場
- anisble部署及包衝突處理
- Caramba Switcher for mac自動鍵盤佈局開關Mac
- git合併分支並處理衝突Git
- windows10玩遊戲鍵盤衝突怎麼辦 win10遊戲與鍵盤衝突解決方法Windows遊戲Win10
- android實現底部彈出框與軟鍵盤衝突(全面屏虛擬鍵適配)Android
- 《java程式設計基礎》javaFX的佈局皮膚Java程式設計
- flutter dialog中軟鍵盤遮擋解決衝突Flutter
- python Django框架符號衝突怎麼處理?PythonDjango框架符號
- 為什麼開啟控制皮膚會閃退 win10控制皮膚閃退的方法Win10
- win10快速啟動intel顯示卡驅動衝突怎麼處理Win10Intel
- Android View 滑動衝突解決方式以及原理AndroidView
- Android 佈局Android
- 颯爽登場《部落衝突》首款中國風皮膚懸念海報露出
- 鍵盤亂鍵怎麼處理 電腦鍵盤按鍵錯亂
- Android com.android.support衝突解決Android
- 使用git處理github中提交有衝突的pull requestGithub
- 精益生產管理諮詢公司如何處理衝突?
- 鍵盤燈在閃
- 移動端軟鍵盤彈出影響頁面佈局問題
- 兩個IO管腳佈局衝突導致Vivado不能生成bit檔案
- 一種巢狀滑動衝突的解決方案巢狀
- win10控制皮膚打不了怎麼辦_win10控制皮膚打不了如何處理Win10
- Android RecyclerView多型別佈局卡片解決方案AndroidView多型型別
- Android學習—— Android佈局Android
- android NestedScrollView和ListView衝突問題AndroidView
- git pull衝突的解決方案Git
- Android輸入鍵盤隱藏解決方案Android
- 一種非巢狀滑動衝突的解決方案巢狀
- win10控制皮膚在哪裡 控制皮膚快捷鍵的開啟方式Win10
- 主鍵衝突引發的死鎖
- win10控制皮膚沒反應如何修復_windows10控制皮膚不能設定怎麼處理Win10Windows
- win10 64g u盤出現驅動衝突如何解決_win10系統u盤出現驅動衝突修復方法Win10
- 360安全衛士與win10衝突怎麼辦_360安全衛士與win10衝突如何處理Win10