快速解決Android適配底部返回鍵等虛擬鍵盤的問題
這個(gè)問題來來回回困擾了我很久,一直沒能妥善解決。
場(chǎng)景1:華為手機(jī)遮擋了屏幕底部。
場(chǎng)景2:進(jìn)入應(yīng)用時(shí),虛擬鍵自動(dòng)縮回,留下空白區(qū)域。
需求:
需要安卓能自適應(yīng)底部虛擬按鍵,用戶隱藏虛擬按鍵時(shí)應(yīng)用要占滿整個(gè)屏幕,當(dāng)用戶啟用虛擬鍵時(shí),應(yīng)用能往上收縮,等于是被底部虛擬按鍵頂上來。
需求很簡(jiǎn)單,實(shí)現(xiàn)起來卻困難重重。
完美解決方案:
解釋一下下面的代碼,就是監(jiān)聽某個(gè)視圖的變化,當(dāng)可以看見的高度發(fā)生變化時(shí),就對(duì)這個(gè)視圖重新布局,保證視圖不會(huì)被遮擋,也不會(huì)浪費(fèi)屏幕空間。這一點(diǎn)尤其可用在像華為手機(jī)等可以隱藏和顯示虛擬鍵盤上導(dǎo)致屏幕變化的手機(jī)上。
首先添加工具類AndroidBug54971Workaround
package com.xxxx.xxxx;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
/**
* Created by win7 on 2016/12/14.
*/
public class AndroidBug54971Workaround {
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
/**
* 關(guān)聯(lián)要監(jiān)聽的視圖
*
* @param viewObserving
*/
public static void assistActivity(View viewObserving) {
new AndroidBug54971Workaround(viewObserving);
}
private View mViewObserved;//被監(jiān)聽的視圖
private int usableHeightPrevious;//視圖變化前的可用高度
private ViewGroup.LayoutParams frameLayoutParams;
private AndroidBug54971Workaround(View viewObserving) {
mViewObserved = viewObserving;
//給View添加全局的布局監(jiān)聽器
mViewObserved.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
resetLayoutByUsableHeight(computeUsableHeight());
}
});
frameLayoutParams = mViewObserved.getLayoutParams();
}
private void resetLayoutByUsableHeight(int usableHeightNow) {
//比較布局變化前后的View的可用高度
if (usableHeightNow != usableHeightPrevious) {
//如果兩次高度不一致
//將當(dāng)前的View的可用高度設(shè)置成View的實(shí)際高度
frameLayoutParams.height = usableHeightNow;
mViewObserved.requestLayout();//請(qǐng)求重新布局
usableHeightPrevious = usableHeightNow;
}
}
/**
* 計(jì)算視圖可視高度
*
* @return
*/
private int computeUsableHeight() {
Rect r = new Rect();
mViewObserved.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
}
然后在你需要解決這個(gè)問題的Activity的onCreate方法的setContentView(R.layout.content_frame);后面添加上
setContentView(R.layout.content_frame); AndroidBug54971Workaround.assistActivity(findViewById(android.R.id.content));
如果你看的懂代碼,你肯定知道assistActivity方法里放入的View是你 要調(diào)整高度的視圖。
其他不完美方案:或多或少在某些情況上會(huì)起不到作用
我一種方法:
android:fitsSystemWindows=”true”
這句話寫在layout的根目錄下,看名字就知道是自適應(yīng)系統(tǒng)窗口。估計(jì)能解決很大一部分手機(jī)了,可是在同事的nexus 4下并沒有什么用。
第二種方法:
我去掉了每個(gè)布局的android:fitsSystemWindows=”true”
在style文件中添加了這句話。
<item name="android:windowTranslucentNavigation">false</item>
注意: 你會(huì)發(fā)現(xiàn)系統(tǒng)報(bào)錯(cuò),這是因?yàn)檫@句話是在API-19后才有的,所以你可以復(fù)制你的style文件,把它放到API-19的文件夾下。這樣的用途就是如果手機(jī)大于等于API19,就會(huì)用API-19的文件夾下的內(nèi)容。否則用原來的style文件。你在API19文件夾下的style文件的根主題中添加上面這句話就OK啦。
本來我以為是完美解決了我的問題??墒潜淮蚰樍?。剛進(jìn)入App時(shí)會(huì)出現(xiàn)上面的場(chǎng)景2的情況。
我一看MainActivity中的onCreate方法的setContentView(R.layout.xxxx);之前有下面的代碼
//控制底部虛擬鍵盤
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
// | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
估計(jì)是這個(gè)項(xiàng)目以前的仁兄為了解決這個(gè)問題添加的。
經(jīng)過多次調(diào)試,我添加了一句話
//控制底部虛擬鍵盤
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
// | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
場(chǎng)景2的情況解決了。這是在虛擬鍵一直存在的情況下沒有問題了,因?yàn)閚exus不能手動(dòng)隱藏虛擬鍵盤,所以我也不清楚是否能在華為等手機(jī)上正常運(yùn)行。TODO。
另外如果想要一直隱藏虛擬鍵盤,點(diǎn)擊屏幕也不會(huì)出現(xiàn)的話,將上面的代碼換成:
//讓虛擬鍵盤一直不顯示 Window window = getWindow(); WindowManager.LayoutParams params = window.getAttributes(); params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_IMMERSIVE; window.setAttributes(params);
以上這篇快速解決Android適配底部返回鍵等虛擬鍵盤的問題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android編程實(shí)現(xiàn)自動(dòng)調(diào)整TextView字體大小以適應(yīng)文字長(zhǎng)度的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)自動(dòng)調(diào)整TextView字體大小以適應(yīng)文字長(zhǎng)度的方法,涉及Android基于TextView類的繼承及Paint屬性操作實(shí)現(xiàn)字體大小自適應(yīng)的相關(guān)技巧,需要的朋友可以參考下2016-01-01
Android開發(fā)之電話撥號(hào)器實(shí)例詳解
這篇文章主要介紹了Android開發(fā)之電話撥號(hào)器,結(jié)合實(shí)例形式詳細(xì)分析了Android電話撥號(hào)器的實(shí)現(xiàn)步驟與具體代碼,并附帶了一個(gè)Android開放電話撥號(hào)器的學(xué)習(xí)筆記,需要的朋友可以參考下2015-12-12
Android ScrollView實(shí)現(xiàn)反彈效果的實(shí)例
這篇文章主要介紹了 Android ScrollView實(shí)現(xiàn)反彈效果的實(shí)例的相關(guān)資料,這里自定義scrollview 并實(shí)現(xiàn)反彈效果,需要的朋友可以參考下2017-07-07
Android 自定義球型水波紋帶圓弧進(jìn)度效果(實(shí)例代碼)
最近小編接到一個(gè)這樣的需求,需要實(shí)現(xiàn)一個(gè)圓形水波紋,帶進(jìn)度,兩層水波紋需要漸變顯示,且外圍有一個(gè)圓弧進(jìn)度。今天小編給大家分享實(shí)例代碼,感興趣的朋友一起看看吧2019-12-12
Android顯示系統(tǒng)SurfaceFlinger分析
本文詳細(xì)講解了Android顯示系統(tǒng)SurfaceFlinger,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12
Android開發(fā)筆記之:消息循環(huán)與Looper的詳解
本篇文章是對(duì)Android中消息循環(huán)與Looper的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android Handle原理(Looper,Handler和Message)三者關(guān)系案例詳解
這篇文章主要介紹了Android Handle原理(Looper,Handler和Message三者關(guān)系案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
Android編程實(shí)現(xiàn)等比例顯示圖片的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)等比例顯示圖片的方法,實(shí)例分析了Android等比例縮放圖片的具體步驟與相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11

