關(guān)于AndroidBug5497Workaround的兼容性問題

背景

最近在給項(xiàng)目添加沉浸式狀態(tài)欄時(shí)遇到了一個(gè)很奇葩的問題,在Android4.4以上系統(tǒng)底部聊天及評(píng)論框不能被系統(tǒng)輸入法頂上去。如下圖1(圖片引用自另外兩種android沉浸式狀態(tài)欄實(shí)現(xiàn)思路,更詳細(xì)的問題描述也可進(jìn)入這個(gè)鏈接查看)。

圖1.png

原因是因?yàn)樵O(shè)置狀態(tài)欄透明后沒有設(shè)置android:fitsSystemWindows="true"這個(gè)屬性。我的解決辦法是使用AndroidBug5497Workaround 類動(dòng)態(tài)計(jì)算布局的高度。這個(gè)方法原始代碼在華為等手機(jī)上存在高度計(jì)算不準(zhǔn)確的兼容性問題。我在源碼的基礎(chǔ)上做了一些修改,目前在華為,小米,三星等手機(jī)上測(cè)試均正常,修改后的代碼如下。

 public class AndroidBug5497Workaround {    
   public static void assistActivity(Activity activity) {      
   new AndroidBug5497Workaround(activity);   
   }  
  private View mChildOfContent;   
  private int usableHeightPrevious;  
  private FrameLayout.LayoutParams frameLayoutParams;  
  private int contentHeight;  
  private   boolean isfirst = true;  
  private   Activity activity; 
  private  int statusBarHeight;  

  private AndroidBug5497Workaround(Activity activity) {      
  //獲取狀態(tài)欄的高度        
  int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");        
  statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);      
  this.activity = activity;
  FrameLayout content = (FrameLayout)activity.findViewById(android.R.id.content);        
  mChildOfContent = content.getChildAt(0);   

  //界面出現(xiàn)變動(dòng)都會(huì)調(diào)用這個(gè)監(jiān)聽事件        
  mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {           
  public void onGlobalLayout() {              
      if (isfirst) { 
            contentHeight = mChildOfContent.getHeight();//兼容華為等機(jī)型                    
            isfirst = false;  
       }               
       possiblyResizeChildOfContent();         
    }      
   });     

   frameLayoutParams = (FrameLayout.LayoutParams)     
   mChildOfContent.getLayoutParams();    
 } 

  //重新調(diào)整跟布局的高度 
 private void possiblyResizeChildOfContent() {  

  int usableHeightNow = computeUsableHeight();       

  //當(dāng)前可見高度和上一次可見高度不一致 布局變動(dòng)      
  if (usableHeightNow != usableHeightPrevious) {            
    //int usableHeightSansKeyboard2 = mChildOfContent.getHeight();//兼容華為等機(jī)型
    int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();    
    int heightDifference = usableHeightSansKeyboard - usableHeightNow;          
    if (heightDifference > (usableHeightSansKeyboard / 4)) {          
     // keyboard probably just became visible        
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){                    
    //frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;                    
    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;                
     } else {                
     frameLayoutParams.height = usableHeightSansKeyboard -heightDifference;                
     }            
   } else {     
   frameLayoutParams.height = contentHeight;        
   }   
     
   mChildOfContent.requestLayout();       
   usableHeightPrevious = usableHeightNow;    
   }  
 }   
 /**     * 計(jì)算mChildOfContent可見高度     ** @return     */    
 private int computeUsableHeight() {  
   Rect r = new Rect();     
   mChildOfContent.getWindowVisibleDisplayFrame(r);       
   return (r.bottom - r.top);  
   }
}

注意事項(xiàng):
使用這個(gè)方法有個(gè)限制是布局內(nèi)得包含有大小可調(diào)的布局如ListView,ScrollView等,并且最大高度(使用權(quán)重weight)至少得大于軟鍵盤和輸入框的高度之和。一般的聊天界面本身就是個(gè)ListView,所有不用擔(dān)心這個(gè)問題。

使用方法

在你的Activity的oncreate()方法里調(diào)用AndroidBug5497Workaround.assistActivity(this);即可。注意:在setContentView(R.layout.xxx)之后調(diào)用。

關(guān)于AndroidBug5497Workaround更詳細(xì)的介紹可以看這里android 軟鍵盤在全屏下的布局計(jì)算問題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容