iOS端:
react
實現功能(iOS和Android):android
一、如何隱藏系統鍵盤
用RN爲iOS和Android雙平臺共用一套自定義鍵盤,使用RN的TextInput做爲輸入框,這樣TextInput該怎麼使用就怎麼使用,所以問題的關鍵就在於如何隱藏系統鍵盤。在iOS中使用inputView
能夠輕鬆實現自定義鍵盤,在Android中自定義鍵盤並不是像iOS那麼直接,須要手動隱藏系統鍵盤,而後監聽輸入框的焦點事件來控制自定義鍵盤的顯示和隱藏。
能夠看如下兩個示例大體瞭解下:
iOS自定義鍵盤
Android 自定義鍵盤實現ios
Android中自定義鍵盤有一個讓人容易誤解的地方,就是
KeyboardView
。能夠在Android 自定義鍵盤實現的Demo中看到有hideSystemSoftKeyboard
方法,用來把EditText的系統鍵盤給隱藏,而後再使用KeyboardView
加入到視圖的底部佈局中,KeyboardView
使用KeyboardView.OnKeyboardActionListener
來監聽鍵盤點擊,使用Keyboard
來給定鍵盤佈局(使用XML描述佈局),而後能夠動態修改Keyboard
和KeyboardView.OnKeyboardActionListener
來實現不一樣的自定義鍵盤。因而可知,使用RN作自定義鍵盤在hideSystemSoftKeyboard
後就能夠打止了,不須要使用KeyboardView
,而是使用ReactRootView
,而後在RN中繪製鍵盤。git
二、自定義鍵盤與原生輸入組件如何交互github
時序圖以下:react-native
RN中文網的自定義鍵盤的GitHub地址:github.com/reactnative…
關於ReactTag的基本原理(iOS版):awhisper.github.io/2016/07/02/…緩存
將上面的流程和代碼弄清後就只剩下RN的鍵盤界面問題了。性能優化
數字鍵盤的佈局和繪製:
參考代碼:github.com/beefe/react…app
字母鍵盤的佈局示意圖:ide
字符鍵盤的佈局示意圖:
字母和符號鍵盤的Tip繪製:
最初想法:每一個key都爲一個單獨的component,裏面有個TouchableHighlight按鈕和與按鈕並級的Tip組件,在onPressIn和onPressOut之間控制Tip的顯示與隱藏。
不可行:以上方案在Android端不可行,由於Android中RN不能使用overflow:visible屬性,在0.41版本中可使用FlatUIImplement實現overflow:visible屬性,可是在0.42及以上版本使用會報錯(不過如今解決了,我沒試)。
曲線救國想法:使用measureLayout
獲得key相對keyboard的位置,而後在keyboard層級繪製Tip,而不在key組件中繪製Tip。這個方案基本可行,可是在Android端仍是須要解決如下問題:
一、Tip可能會超過keyboard的邊界,所以第一行仍是會被截掉,因此須要把鍵盤的高度要加高一些以容納第一行的Tip。
二、keyboard的背景色會遮擋下層視圖,因此要對keyboard的背景作透明。
三、keyboard加高的部分會遮擋下層視圖對手勢的響應,因此對加高的部分要放棄事件響應。
解答參考了stackoverflow上的提問:Element overflow hidden in React-Native Android
繪製難點:
iOS端Tip外形的繪製:使用react-native-svg繪製,個人繪製代碼。
Android陰影的實現:使用以react-native-svg爲基庫作成的react-native-shadow。
注:我並無在Android中使用陰影樣式,而是仿照f8app的寫法在不一樣平臺使用不一樣樣式。
由於字母和字符鍵盤一次性繪製了30多個按鈕在屏幕上,會致使在低端Android機能感受到卡頓(調成Debug模式會很明顯,在Dev下打開'Show Perf Monitor'會發現首屏渲染時JS線程掉幀很明顯),我在這作了個測試:一次性渲染40個按鈕,能夠運行看一下卡頓狀況。
所以渲染出的數字、字母和字符鍵盤的DOM分別要被緩存起來,這樣纔不會在頻繁切換鍵盤時感受到卡頓。
若是首屏出現的是數字鍵盤,那麼字母鍵盤和字符鍵盤就不該該被放在渲染樹中,作到用到特定鍵盤時再去加載這個鍵盤。
根據React 源碼剖析系列 - 難以想象的 react diff,要作到高效的渲染儘可能不能改變Dom樹的結構,React並無提供
removeView
和addView
之類的方法(固然你能夠經過帶_
的私有方法實現),Element(使用JSX或者React. createElement建立出來的)其實並不佔多大空間,真正渲染的是DOM(能夠經過ref獲取),使用DisplayView能夠控制DOM的隱藏和顯示,讓視圖在第一次使用時纔在DOM樹建立,在隱藏和顯示時不用改變DOM樹的結構。
react-native-storybook
UI組件的開發工具,能夠瀏覽組件庫,查看各個組件的各個狀態,以及開發和測試組件。
歡迎關注個人簡書主頁:www.jianshu.com/u/b92ab7b3a… 文章同步更新^_^