編輯:關於Android編程
先通過一個頁面看下事情的來龍去脈,頁面如下所示:
這個頁面剛好一屏幕大小,所以沒有滾動條,因為“保存”鍵上面那個項目備注是需要用戶去填寫的,當他點擊後就會出現虛擬鍵盤,但安卓手機彈出鍵盤會遮住這個輸入框,以至於用戶看不見了。蘋果手機天然不會喔,蘋果手機的鍵盤彈出來是占了下面的位置,從而把頁面推了上去,整個頁面就縮小了就不會出現這樣的情況。安卓手機情況如下圖:
我不停嘗試去解決這個問題,但最終都不成功。
思考一:
如果能模仿蘋果一樣,當鍵盤彈出來的時候,將整個頁面縮小成頁面底部剛好貼著鍵盤,那就完美了。但是這個想法最大的問題就是,不能准確拿到虛擬鍵盤的高度(後來測試時發現,虛擬鍵盤原來還可以改變大小……所以這個高度更不可能拿到了……),但即使拿到高度,能完成當備注那個textarea onfocus時,鍵盤彈出並准確計算成整個頁面縮小成頁面底部剛好貼著鍵盤這個效果,還有一個最終大坑!就是沒有辦法監聽到虛擬鍵盤什麼時候被用戶收起來!這樣一來就不知道什麼時候去還原這個頁面了……雖然onblur事件可以在失去焦點時去還原這個頁面,但安卓用戶的習慣操作應該是按手機上的物理返回鍵或者虛擬鍵盤上的那個收起鍵盤的按鈕,問題是無論返回還是收起鍵盤,焦點還是在那裡,沒有失去呀,這就沒辦法了……所以最終的問題關鍵是,怎樣監聽到虛擬鍵盤……
思考二:
嘗試了一個方法效果已經很接近了。代碼如下:
<div id="fix-hegiht" ></div>
其實就是在文本框onfocus時,把上面這個空白高度的div顯示出來,於是就能把頁面撐高,就會出現滾動條,效果挺好如下圖:
而且收鍵盤後,竟然頁面會回到頂部(我懷疑觸發了resize事件,但經測試,無論鍵盤彈出收起都沒觸發哎,遺憾),這不就是想要的效果了嗎!如下圖:
會發現雖然回到了頂部,看起來好像跟一開始沒有滾動條的樣子一樣,但現在用戶是可以滾動的,因為那個負責撐高的空div仍然在那裡,如果用戶滾下去就會看到一大片空白,這肯定是要處理掉的。於是問題又到了“什麼時候去刪了這個空div”?最好的當然是能監聽到鍵盤什麼時候被收起來啦,但這個似乎不太可能。於是我想,能不能當滾動條滾動到空div的地方就把它刪了。確實可以這樣子,但體驗不好啊,突然就閃了一下,而且,如果當用戶彈出鍵盤時去操作可以滾動的頁面,滾到空div的地方就刪了這個div,那瞬間輸入框又被蓋住了……
我還想,能不能滾動條滾到空div的地方,就不能往下滾了呢?如果這樣,用戶滾不下去,那留著這個空白div也沒問題啊。但是這個想法卻實現不了,搞來搞去沒辦法搞出來。
思路三:
我就想這個虛擬鍵盤擋住輸入框的問題應該到處可見啊,各種注冊頁面估計都有,那怎麼會這麼多年來都用安卓的我竟然沒覺得這是個問題!?於是我跑去隨便找一個注冊頁面(如搜狐郵箱)http://wap.mail.sohu.com/,截圖如下:
竟然可以!?整個頁面往上挪了一點,但沒出現滾動條!!這究竟是怎麼做到的!!??我就奇怪是不是浏覽器問題,因為這個是手機自帶的浏覽器訪問的。於是我開微信,然後點開這個網站,果然如下圖:
原來是微信的浏覽器就會這樣子……最後跑去QQ浏覽器那裡看,也有人問這個問題,估計是X5內核升級之後的BUG……最後為了能使用,還是將就使用空白div撐高的方法。在尋找解決方法的過程中,還發現有段很漂亮的代碼。來自http://efe.baidu.com/blog/mobile-fixed-layout/ 也許以後會用上,可以用來判斷滾動條是否到某個位置,還有滑動的方向,以此來判斷什麼時候阻止滾動條滾動。代碼已經過詳細注釋:
<script type="text/javascript"> // 防止內容區域滾到底後引起頁面整體的滾動 var content = document.querySelector('main'); var startY; content.addEventListener('touchstart', function (e) { //起始位置 startY = e.touches[0].clientY; }); content.addEventListener('touchmove', function (e) { // 高位表示向上滾動 // 底位表示向下滾動 // 1容許 0禁止 var status = '11'; var ele = this; //當前位置 var currentY = e.touches[0].clientY; //如果垂直偏移量scrollTop為0,說明要麼內容小於容器沒有滾動條,要麼大於容器但滾動條在頂部 if (ele.scrollTop === 0) { // 如果內容小於容器則同時禁止上下滾動,若大於則可以向下滾動 status = ele.offsetHeight >= ele.scrollHeight ? '00' : '01'; } else if (ele.scrollTop + ele.offsetHeight >= ele.scrollHeight) { /* 1.垂直偏移量scrollTop+整個元素的尺寸offsetHeight(包括邊框)=整個內容區域scrollHeight 證明已經滾到底部了只能向上滾動; 2.其中offsetHeight(包括邊框)是否要換成clientHeight(不包括邊框)? */ status = '10'; } //若status==11則上面三種情況都不是,這種情況是有滾動條且滾動條不在頂部也不在底部 if (status != '11') { // 判斷當前的滾動方向 var direction = currentY - startY > 0 ? '10' : '01'; /* 1.操作方向和當前允許狀態求與運算,運算結果為0,就說明不允許該方向滾動,則禁止默認事件,阻止滾動 2.status為00,說明沒有滾動條,此時無論direction是上還是下,都要阻止滾動 3.status為01,說明有滾動條,可以向下滾動,此時direction為01則符合向下滾動 4.status為10,說明有滾動條,可以向上滾動,此時direction為10則符合向上滾動 5.綜上a.沒有滾動條 b.滾動條在頂部但還向上滾動 c.滾動條在底部但還向下滾動 都要阻止滾動 */ if (!(parseInt(status, 2) & parseInt(direction, 2))) { stopEvent(e); } } }); </script>
這裡用到了HTML5的touch事件,分別touch事件有四個:touchstart、touchmove、touchend、touchcancel。當你滑動屏幕的時候,他們的觸發順序是:
touchstart:當手指接觸屏幕時觸發
touchmove:當已經接觸屏幕的手指開始移動後觸發
touchend:當手指離開屏幕時觸發
touchcancel:當某種touch事件非正常結束時觸發
所以可以通過上圖這些屬性去獲取touch時的位置。
以上內容給大家介紹了安卓輸入框被虛擬鍵盤擋住的問題(微信開發),希望對大家有所幫助!
一、概述本文之前,先提一下關於上篇博文的100多萬訪問量請無視,博文被刷,我也很郁悶,本來想把那個文章放到草稿箱,結果放不進去,還把日期弄更新了,實屬無奈。
我們在開發Android的時候經常通過Adapter把數據和UI對象連接在一起,spinner、ListView之類的控件都可以用適配器來自定義其組建,使其更加豐富。適配
.xml代碼如下: 顯示如下:
android4.4 webview chromium是單進程的,圖中所有組件都運行在Browser進程中。 按從上而下的順序介紹這張圖中與顯示網頁相關的chromiu