Tüm düzeni görüntüleme Zorlama nasıl yenilenir?


173

Activity.onResume () yönteminde, ana düzen kaynak görünümünü yeniden çizme / yenileme zorlamak istiyorum. Bunu nasıl yapabilirim ?

Ana mizanpaj görünümü ile, benim Activity.onCreate () içinde çağrılan birini (aşağıda 'R.layout.mainscreen') kastediyorum: -

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

Çevrenizdeki Doğrusal / Göreli / WhateverLayout'unuzu adlandırmayı, üzerinde findViewById öğesini çağırmayı ve ardından bunun üzerinde geçersiz kılmayı () çağırmayı denediniz mi? (Bunu bir cevap olarak koyardım, ancak ebeveynlerin de çocukları geçersiz kılıp kılmadıklarını bilmiyorum ve bunu test edebileceğim bir yer değilim.)
Ben Williams

Ayrıca teşekkürler ! Yine de bununla mücadele ediyorum. Aşağıda neler gönderdiğime bir göz atabilir misiniz?
Temamın

Yanıtlar:


149

Soruyu kesin olarak cevaplamak için: invalidate () kullanın:

public void invalidate () Başlangıç ​​tarihi: API Düzey 1

Tüm görünümü geçersiz kılın. Görünüm görünürse, gelecekte bir noktada onDraw (Tuval) çağrılır. Bu bir UI iş parçacığından çağrılmalıdır. Kullanıcı arabirimi olmayan bir iş parçacığından aramak için postInvalidate () öğesini çağırın.

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

Etkinlik yeniden başladığında, her Görünüm'ün kendisini çizmesini sağlar. Invalidate () çağrısına gerek yoktur. Temayı uygulamak için, herhangi bir Görünüm çizilmeden önce, yani öncesetContentView(R.layout.mainscreen);

public void setTheme (int resid) Tarih: API Seviye 1

Bu bağlam için temel temayı ayarlayın. Bu görünüm Bağlamda herhangi bir görünüm başlatılmadan önce çağrılmalıdır (örneğin, setContentView (View) veya inflate (int, ViewGroup) çağrılmadan önce).

API doküman referansı burada: http://developer.android.com/reference/android/view/ContextThemeWrapper.html#setTheme%28int%29

OnDraw () yöntemi zaten örneklenmiş Görünümler üzerinde çalıştığından, setTheme çalışmaz. Temalar hakkında hiçbir deneyimim yok, ancak düşünebileceğim iki alternatif seçenek:

  1. bunun yerine onCreate () içindeki setTheme öğesini çağırın veya
  2. setContentView (R.layout.mainscreen) öğesini yeniden yapın; tüm yerleşimi eski haline döndürmeye zorlamak.

Teşekkürler ! Bu iyi çalışıyor, ama beklediğim görmüyorum. Kodunuzu çalıştırmadan hemen önce Activity.setTheme (newtheme) komutunu çalıştırıyorum, ancak bu geçersiz kılınan () çağrı temanın değişmesine neden olmuyor (örneğin Karanlıktan Aydınlığa). Bunu geçersiz kılmalı mı ()?
MickeyR

@MickeyR hayır, olmamalı. Güncellenmiş cevabımı kontrol et. Bu iki seçenek işe yaramazsa, Etkinliğinizi yeniden başlatmanız gerekir.
Aleadam

Seçenek (1) işe yarıyor. Uygulamam doğru tema ile başlayacak, ancak çalışırken değiştirirsem, onCreate () öğesinin tekrar çağrılabilmesi için uygulamamı yeniden başlatmam gerekiyor.
MickeyR

Seçenek (2), gitmek istediğim yoldur. Yani, çalışırken tema değiştirildiğinde, bunu yapmak için onRestart () istedim: - setTheme (getPreferenceTheme ()); ve setContentView (R.layout.main); Ama bu benim temamı değiştirmiyor. Bu ikinci seçeneği çalıştıramadım ...?!
MickeyR

Seçenek (2) çalışmasını sağlamak için 'görünüm hiyerarşisini yeniden şişirmek' gerektiğini anladım. Bunu başarmak için farklı şeyler denedim, ama bunun ne anlama geldiğinden ve nasıl yapılacağından emin değilim.
MickeyR

41

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


3
Teşekkürler ! Aynı cevabı yukarıda Aleadam'a gönderdim. Bu invalidate (), aktivite temasının yenilememize neden olmamalı.
MickeyR

36

Deneyin recreate(), bu Faaliyetin yeniden yaratılmasına neden olacaktır.


4
Bu konudaki tüm seçenekleri denedim ve bu en az istenmeyen yan etkilerle çalışan tek seçenektir.
swooby

1
Ben onResumeyöntemde bunu yapmak gerekiyorsa . Bu bana infinte döngü vermek: /
Kamil Witkowski

Peki u gerçekten ihtiyaç kadar kullanmak tavsiye etmiyoruz. Sonsuz döngüden kaçınmak için paylaşılan tercihlere bazı bayraklar kaydedebilirsiniz.
Mohanad ALKHOULI

Bu işe yarıyor ama gerçek üretim modu uygulamasında kullanmanızı tavsiye etmem. Sadece hata ayıklama modu için ihtiyacım vardı, bu yüzden tüm UI yenilemesinin yan etkisi kritik değil.
drorsun

31

Çözüm:

Beyler ben senin Çözümleri tüm çalıştı ama onlar benim için çalıştı vermedi, ben set zorunda setVisibility için EditText ait GÖRÜNÜR ve bu EditText sonra görünür olmalıdır scrollview ama etkili olması için kök görünümü yenilemek edemedi. Görünümü yenilemem gerektiğinde sorunumu çözdüm, böylece ScrollView görünürlüğünü GONE olarak değiştirdim ve sonra tekrar etkili olması için GÖRÜNÜR olarak ayarladım ve benim için çalıştı. Bu kesin bir çözüm değil, sadece işe yaradı.

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

2
@MickeyR Lütfen bir cevap kabul edin, böylece insanlar çözümü kolayca bulabilir
Naveed Ahmad

vay .. Ben de önerilen tüm sollutions denedim ama bu tek çalışan gibi görünüyor, ama biraz korkunç ...
Rik van Velzen

@MickeyR'nin bu cevabı neden kabul etmediğini bilmiyorum
Naveed Ahmad

1
@NaveedAhmad Teşekkürler! Elimden gelenin 4 saatini yaptıktan sonra işe yarayan tek çözüm buydu.
Codelicious

10

Görünüşe göre invalidate()veya postInvalidate()kök düzeninde arama yapmak , çocuk görünümlerinin yeniden çizileceğini garanti ETMEZ. Benim özel durumumda, kök düzenim bir TableLayout idi ve TableRow ve TextView sınıfında birkaç alt öğe vardı. Arayan postInvalidate()ya requestLayout()hatta forceLayout()kök TableLayout nesne yeniden çizilmesi düzeninde herhangi TextView'lar neden olmadı.

Yani, ben sonuçta ne yinelenen bu TextViews arıyor düzeni ayrıştırmak ve sonra postInvalidate()bu TextView nesnelerin her birini çağırmak oldu.

Kod GitHub'da bulunabilir: https://github.com/jkincali/Android-LinearLayout-Parser


9

Aksi takdirde bunu da deneyebilirsiniz.

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

4
Bunun için teşekkürler ! Ancak, bu, sahip olduğum tüm Görünümleri (TextView, Buttons vb.) Kaldırdı, ancak yeniden
çizmedi

görünümünüzü yenilemeniz gerekiyorsa, çizim işlevini tekrar çağırmanız gerekir. önceki görünümü temizledikten sonra.
Datta Kunde

4

İçerik görünümünüzü devam ettirmeniz yeterlidir

setRest içerisindeki setContentView (R.layout.yourview) ..

Misal:

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

Merhaba ben bunu denedim ve liste görünümünde aynı veri iki kez çekilir, bu yüzden 4 satır vardı ve ferahlatıcı beşinci bir satır eklemek gerekiyordu, bunun yerine 10, sonra 15 ile bitirmek gerekiyordu ... ne yapmalı?
iOSAndroidWindowsMobileAppsDev

4

Tema sorunu için bu geçici çözümü deneyin:

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

Bu, tema değişiklikleriyle yeniden yüklemenizi sağlar ve animasyonları gizler.


3

Ben de bu sorunu yaşıyordum ama Farhan'ın kullanımından setContentView()sonra bunu yaptım. setContentView()kendi başına kullanmak yeterli değildi. Tüm görüşlerimi bilgi ile doldurmam gerektiğine karar verdim. Bunu düzeltmek için sadece bu kodu başka bir yönteme (yaptım derdim) çıkardım ve onCreateyöntemimde sadece bu derlemeyi çağırıyorum. Şimdi ne zaman benim olay "yenileme" istiyorum ne zaman gerçekleşir Ben sadece inşa çağırmak, yeni bilgi vermek (hangi oluşturmak için parametre olarak geçirir) ve yenilenmiş bir etkinlik var.



0

Bunun güvenli olup olmadığını bilmiyorum ama benim için çalıştı. Ben biraz kendimi bu sorunla karşılaştık ve denenmiş invalidate()ve requestLayout()ama boşuna. Bu yüzden her şeyi onCreate(null)tekrar aradım ve işe yaradı. Bu güvensizse lütfen bana bildirin. Umarım bu birisine yardım eder.


SavedInstanceState öğesini null değerine ayarlıyorsunuz, bu da beklenmeyen davranışlara neden olabilir. Daha fazla bilgi için: stackoverflow.com/questions/15115975/…
PhilipB

0

Düzenimi yenilemek için bu şekilde kullandım

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'u genişleten bir görünümü temizlemek için yalnızca yöntemi kullanmanız gerekir removeAllViews()

Tıpkı bunun gibi (adlı bir ViewGroup'unuz varsa myElement):

myElement.removeAllViews()


-1

İyi bir yaklaşım olup olmadığından emin değilim ama bunu her seferinde çağırıyorum:

setContentView(R.layout.mainscreen);

-8

Sadece niyetini kullanarak etkinliği tekrar çağırın. Örneğin, MainActivity'nin düzenini yenilemek için şunu yapın:

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

2
Bu çirkin! Bunu yaptığınızda, yığına yeni bir etkinlik eklersiniz, bu nedenle geri düğmesine bastığınızda aynı etkinliğe geri dönersiniz.
Daniel Beltrami
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.