2017-01-31 54 views
1

對於我正在開發的應用程序,我想在用戶輸入後重新加載用戶界面(基本上在對用戶進行更改後重置它)。我想嘗試避免摧毀/重新創建活動,並使用setContentView(),因爲它速度更快。fitsSystemWindows =「true」在調用setContentView()後不起作用

但是,當我這樣做時,我遇到了一個問題:新創建的用戶界面不尊重fitsSystemWindows="true",它的一部分結束在android狀態欄後面。

我管理煮沸它下降到上面的示例代碼來測試它:

layout.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/mainContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true" 
    android:orientation="vertical"> 
    <Button 
     android:text="Button" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/button" /> 
</LinearLayout> 

MainActivity.java

import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.layout); 

     Button button = (Button) findViewById(R.id.button); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       reloadUI(); 
      } 
     }); 

    } 

    public void reloadUI() { 
     setContentView(R.layout.layout); 
    } 
} 

當我加載應用程序,我得到了預期的佈局,這是一個簡單的按鈕,在屏幕上方,正好在狀態b之下AR:

enter image description here

但是,一旦我點擊它調用setContentView第二次(顯示相同的XML)按鈕,該按鈕獲取狀態欄背後:

enter image description here

調用mainContainer.getMeasuredHeight()檢查應用程序第一次啓動時發生的1848px(在1920px高的屏幕上,所以它的高度比整個屏幕小72px,而72px是狀態欄的高度),但是一旦我再次調用setContentView mainContainer.getMeasuredHeight()給我1920px。

我在這裏錯過了什麼嗎?我可以強制mainContainer使用72px頂部填充來粘貼到1848px的高度,但我寧願避免這樣的醜陋黑客。

+0

你爲什麼要叫'再次setContentView'?相反,你可以使整個'viewgroup'無效。 – Wizard

+0

我試過了,但它沒有正確重置所有東西。例如在我的用例中,有一些用戶可以設置爲特定顏色的自定義視圖(存儲在自定義視圖類中),並且在調用invalidate時不會重置爲默認視圖,而只是重繪UI。我可以重構我的應用程序的一部分來正確處理invalidate,但我認爲使用setContentView會更快地獲得全新的啓動並將UI重新加載到默認狀態。 – TheAthenA714

回答

0

我有同樣的問題。我的解決方案是更改rootViewmarginToppaddingTop以適應手動View

0

所以,你想要的是要求框架再次發送WindowInsets到你的根視圖。這正是ViewCompat.requestApplyInsets(View)將會執行的操作:

要求執行一個新的發送View.onApplyWindowInsets(WindowInsets)。這可以回到View.requestFitSystemWindows()哪裏可用。

應用只是一個行應該解決您所有的顧慮:

 


    public void reloadUI() { 
     setContentView(R.layout.layout); 
     // `R.id.mainContainer` is the id of the root view in `R.layout.layout` 
     ViewCompat.requestApplyInsets(findViewById(R.id.mainContainer)); 
    } 

 
相關問題