2017-01-31 11 views
1

개발중인 앱의 경우 사용자 입력 후 UI를 다시로드하고 싶습니다 (기본적으로 변경 한 후에 완전히 다시 설정합니다). 나는 활동을 파괴/재창조하는 것을 피하고 더 빠른 것이기 때문에 setContentView()을 사용하고 싶었다.fitsSystemWindows = "true"는 setContentView()를 호출 한 후 작동하지 않습니다.

그러나 그럴 경우 문제가 발생합니다. 새로 만든 UI는 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

mainContainer.getMeasuredHeight()를 호출 : 나는 setContentView 두 번째 (같은 XML을 보여주는)를 호출 버튼을 클릭하면

enter image description here

그러나 버튼은 상태 표시 줄 뒤에 도착 무슨 일이 일어 났는지 확인하려면 앱의 첫 번째 시작에서 1848px를 제공합니다 (높이가 1920px 인 화면에서 높이가 전체 화면보다 72px 작고 상태 막대의 높이가 72px 임). 그러나 일단 setContentView를 다시 호출하면 mainContainer.getMeasuredHeight() 날 1920px 준다.

여기에 뭔가가 있습니까? mainContainer를 72px의 위쪽 패딩으로 1848px 높이에 고정시킬 수는 있지만 이렇게 추한 해킹을 피하는 것이 좋습니다.

+0

왜 다시'setContentView' 호출? 대신'viewgroup' 전체를'무효화 '할 수 있습니다. – Wizard

+0

나는 그것을 시도했지만 모든 것을 올바르게 재설정하지는 않는다. 예를 들어, 유스 케이스에서는 사용자가 특정 색상 (사용자 정의보기 클래스 내에 저장 됨)을 설정할 수있는 사용자 정의보기가 있으며, 무효화를 호출 할 때 기본값으로 재설정되지 않고 UI 만 다시 그려집니다. 리팩터링 기능을 사용하면 앱의 일부를 제대로 처리 할 수 ​​있지만 setContentView를 사용하면 새로운 시작을 얻고 UI를 기본 상태로 다시로드하는 것이 더 빠를 것이라고 생각했습니다. – TheAthenA714

답변

0

나는 동일한 문제가있었습니다. 제 해결책은 rootViewmarginTop 또는 paddingTopView에 수동으로 변경하는 것입니다.

0

그래서, 다시 한 번 WindowInsets을 루트보기로 보내도록 프레임 워크에 요청하는 것이 좋습니다. 정확히 은 다음과 같이 처리 할 것입니다.

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)); 
    }