전체 레이아웃보기를 새로 고치는 방법?


173

Activity.onResume () 메서드와 같이 기본 레이아웃 리소스보기를 다시 그리거나 새로 고치려고합니다. 어떻게해야합니까?

기본 레이아웃보기에서, 나는 다음과 같이 내 Activity.onCreate ()에서 호출되는 것 (아래의 'R.layout.mainscreen')을 의미합니다.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainscreen);
}

둘러싼 Linear / Relative / WhateverLayout의 이름을 지정하고 findViewById를 호출 한 다음 invalidate ()를 호출 했습니까? (나는 이것을 대답으로 넣었지만 부모를 무효화하는 것이 아이들을 무효화하는지 테스트 할 수있는 곳이 아닌지 모르겠다.)
Ben Williams

도 감사하다 ! 그래도 여전히 어려움을 겪고 있습니다. 아래에 게시 한 내용을 살펴볼 수 있습니까? 테마를 새로 고치려면이 코드 (또는 다른?)가 필요합니다.
MickeyR

답변:


149

질문에 엄격히 대답하려면 invalidate ()를 사용하십시오.

public void invalidate () 이후 : API 레벨 1

전체보기를 무효화하십시오. 보기가 표시되면 나중에 언 드로우 (Canvas)가 호출됩니다. UI 스레드에서 호출해야합니다. 비 UI 스레드에서 호출하려면 postInvalidate ()를 호출하십시오.

ViewGroup vg = findViewById (R.id.mainLayout);
vg.invalidate();

이제 활동이 재개되면 모든보기가 스스로 그려집니다. invalidate ()를 호출 할 필요가 없습니다. 테마를 적용하려면보기가 그려지기 전에 (즉, 전에) 수행해야합니다.setContentView(R.layout.mainscreen);

공개 무효 setTheme (int resid) 이후 : API 레벨 1

이 컨텍스트의 기본 테마를 설정하십시오. 컨텍스트에서 뷰를 인스턴스화하기 전에 (예 : setContentView (View) 또는 inflate (int, ViewGroup)을 호출하기 전에) 호출해야합니다.

API 문서 참조는 다음과 같습니다. http://developer.android.com/reference/android/view/ContextThemeWrapper.html#setTheme%28int%29

onDraw () 메소드는 이미 인스턴스화 된 뷰에서 작동하므로 setTheme이 작동하지 않습니다. 테마에 대한 경험이 없지만 생각할 수있는 두 가지 대안은 다음과 같습니다.

  1. 대신 onCreate ()에서 setTheme를 호출하거나
  2. redo setContentView (R.layout.mainscreen); 모든 레이아웃을 강제로 복원합니다.

감사 ! 이것은 괜찮아요, 그러나 내가 기대 한 것을 보지 못했습니다. 코드를 실행하기 전에 Activity.setTheme (newtheme)을 실행하지만이 invalidate () 호출로 인해 테마가 변경되지는 않습니다 (예 : Dark에서 Light로). invalidate () 할 수 있어야합니까?
MickeyR

@MickeyR 아니오, 안됩니다. 업데이트 된 답변을 확인하십시오. 이 두 가지 옵션이 작동하지 않으면 활동을 다시 시작해야합니다.
Aleadam

옵션 (1)이 작동합니다. 내 앱은 올바른 테마로 시작하지만 실행 중에 변경하면 onCreate ()가 다시 호출되도록 앱을 다시 시작해야합니다.
MickeyR

옵션 (2)는 내가 가고 싶은 길입니다. 따라서 실행하는 동안 테마가 변경되면 onRestart ()가 다음을 수행하기를 원했습니다 .- setTheme (getPreferenceTheme ()); 그리고 setContentView (R.layout.main); 그러나 이것은 내 테마를 변경하지 않습니다. 이 두 번째 옵션을 사용할 수 없습니다 ...?!
MickeyR

옵션 (2)가 작동하려면 '보기 계층 구조를 다시 팽창시켜야합니다. 나는 이것을 달성하기 위해 다른 것들을 시도했지만 이것이 이것이 무엇을 의미하는지, 어떻게 해야하는지 확실하지 않습니다.
MickeyR

41

시험 getWindow().getDecorView().findViewById(android.R.id.content).invalidate();


3
감사 ! 위에서 Aleadam에게 게시 한 것과 같은 답변입니다. 이 invalidate ()는 활동 테마를 새로 고치지 않으므로 필요한 것입니다.
MickeyR

36

recreate()이 활동이 다시 작성되도록 시도하십시오 .


4
이 스레드의 모든 옵션을 시도했지만 이것이 가장 바람직하지 않은 부작용으로 작동하는 유일한 옵션입니다.
swooby

1
onResume방법 으로이 작업을 수행하려면 어떻게해야합니까 ? 이주고 나를 infinte 루프 : /
카밀 위트 코우 스키

글쎄, 난 정말 필요할 때까지 사용하지 않는 것이 좋습니다. 무한 루프를 피하기 위해 공유 환경 설정에 일부 플래그를 저장할 수 있습니다.
Mohanad ALKHOULI

이것은 작동하지만 실제 프로덕션 모드 앱에서는 사용하지 않는 것이 좋습니다. 디버그 모드에서만 필요하므로 전체 UI 새로 고침의 부작용이 중요하지 않습니다.
drorsun

31

해결책:

여러분의 모든 솔루션을 시도했지만 효과가 없었습니다 .EditVis 의 EditVisibility를 VISIBLE 로 설정 해야 하며이 EditText가 ScrollView에 표시되어야 하지만 루트보기를 새로 고쳐서 적용 할 수는 없었습니다. 뷰를 새로 고쳐야 할 때 문제를 해결하여 ScrollView 가시성을 GONE으로 변경 한 다음 다시 VISIBLE로 설정하여 효과를 보았습니다. 이것은 정확한 해결책은 아니지만 효과가 있습니다.

 private void refreshView(){
    mScrollView.setVisibility(View.GONE);
    mScrollView.setVisibility(View.VISIBLE);
}

2
@MickeyR 사람들이 해결책을 쉽게 찾을 수 있도록 답을 받아주십시오
Naveed Ahmad

와우 .. 나는 또한 제안 된 모든 용제를 시도했지만 이것은 유일하게 작동하는 것 같지만 끔찍한 일입니다 ...
Rik van Velzen

@MickeyR이이 답변을 수락하지 않는 이유를 모르겠습니다.
Naveed Ahmad

1
@NaveedAhmad 감사합니다! 내가 할 수있는 모든 일을 한 후 4 시간이 지난 유일한 해결책이었습니다.
Codelicious

10

호출 invalidate()하거나 postInvalidate()루트 레이아웃에서 자식 뷰가 다시 그려지는 것은 아닙니다. 필자의 경우 루트 레이아웃은 TableLayout이며 TableRow 및 TextView 클래스의 여러 자식이 있습니다. postInvalidate(), 또는 루트 TableLayout 객체를 호출 requestLayout()해도 forceLayout()레이아웃의 TextView가 다시 그려지지 않았습니다.

그래서 마지막으로 레이아웃을 재귀 적으로 파싱하여 TextView를 찾고 postInvalidate()각 TextView 객체 를 호출 했습니다.

코드는 GitHub에서 찾을 수 있습니다 : https://github.com/jkincali/Android-LinearLayout-Parser


9

그렇지 않으면 당신도 이것을 시도 할 수 있습니다-

ViewGroup vg = (ViewGroup) findViewById (R.id.videoTitleTxtView);
 vg.removeAllViews();
 vg.refreshDrawableState();

4
이것에 감사드립니다! 그러나 이것은 내가 가진 모든보기 (TextView, 버튼 등)를 제거했지만 다시 그리지 않았습니다. 화면이 비어 있습니다 ...
MickeyR

뷰를 올바르게 새로 고친 다음 그리기 기능을 다시 호출해야합니다. 이전보기를 청소 한 후
Datta Kunde

4

onresume에서 콘텐츠보기를 설정하기 만하면됩니다.

onResume 내부의 setContentView (R.layout.yourview).

예:

@Override
public void onResume(){
super.onResume();
setContentView(R.layout.activity_main); 
postIncomeTotals();
}

안녕하세요,이 시도하고 목록보기에서 동일한 데이터가 두 번 당겨졌습니다. 따라서 4 개의 행이 있고 새로 고침이 다섯 번째 행을 추가 해야하는 경우 대신 10, 15로 끝납니다 ... 무엇을해야합니까?
iOSAndroidWindowsMobileAppsDev

4

테마 문제에 대해이 해결 방법을 시도하십시오.

@Override
public void onBackPressed() {
    NavUtils.navigateUpTo(this, new Intent(this,
            MyNeedToBeRefreshed.class));
}

3
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);

이를 통해 테마 변경 사항을 다시로드하고 애니메이션을 숨길 수 있습니다.


3

나는이 문제를 겪고 있었지만 Farhan의 사용 리드에 따라 setContentView()그렇게했습니다. 사용 setContentView()자체로하는 것은 매우 충분하지 않았다. 정보로 모든 견해를 다시 채워야한다는 것을 알았습니다. 이 문제를 해결하기 위해 방금 모든 코드를 다른 메소드로 가져 왔습니다 (빌드라고 함). 내 onCreate메소드 에서는 해당 빌드를 호출합니다. 이제 내 이벤트가 발생하면 내 활동이 "새로 고침"되기를 원할 때마다 빌드를 호출하고 새로운 정보 (작성할 매개 변수로 전달)를 제공하면 새로 고친 활동이 있습니다.



0

이것이 안전한지 아닌지는 모르겠지만 저에게 효과적이었습니다. 나는 좀 자신은이 문제에 달려 시도 invalidate()하고 requestLayout()있지만 소용. 그래서 방금 onCreate(null)다시 전화를 걸어서 효과가있었습니다. 이것이 안전하지 않은 경우 알려주십시오. 이것이 누군가를 도울 수 있기를 바랍니다.


savedInstanceState를 null로 설정하여 예기치 않은 동작이 발생할 수 있습니다. 자세한 정보 : stackoverflow.com/questions/15115975/…
PhilipB

0

이것이 내가 레이아웃을 새로 고치는 데 사용한 방법입니다

Intent intent = getIntent();
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);

0

ViewGroup을 확장하는 뷰를 지우려면 메소드 만 사용하면됩니다. removeAllViews()

다음과 같이 (ViewGroup이있는 경우 myElement) :

myElement.removeAllViews()



-8

의도를 사용하여 활동 자체를 다시 호출하십시오. 예를 들어 MainActivity의 레이아웃을 새로 고치려면 다음과 같이하십시오.

startActivity(new Intent(MainActivity.this, MainActivity.class));

2
못 생겼어! 이 작업을 수행하면 스택에 새 활동이 추가되므로 뒤로 버튼을 누르면 동일한 활동으로 돌아갑니다.
다니엘 벨트 라미
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.