संपूर्ण लेआउट को कैसे बाध्य करें ताज़ा करें देखें?


173

मैं एक्टिविटी.ऑन्यूस्यूम () पद्धति के अनुसार मुख्य लेआउट संसाधन दृश्य को फिर से तैयार / ताज़ा करने के लिए बाध्य करना चाहता हूं। मैं यह कैसे कर सकता हूँ ?

मुख्य लेआउट दृश्य से, मेरा मतलब है कि नीचे ('R.layout.mainscreen') जो कि मेरी गतिविधि.ऑनक्रिट () में कहा जाता है, जैसे: -

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

क्या आपने अपने संलग्नक नामकरण / सापेक्ष / जो कुछ भी नामकरण करने की कोशिश की है, उस पर findViewById को कॉल करें, और फिर उस पर अमान्य () कॉलिंग करें? (मैं इसे एक उत्तर के रूप में रखूंगा, लेकिन मुझे नहीं पता कि क्या माता-पिता को अमान्य करना भी बच्चों को अमान्य करता है और मैं कहीं ऐसा नहीं हूं जो मैं इसका परीक्षण कर सकता हूं।)
बेन विलियम्स

धन्यवाद भी ! मैं अभी भी इसके साथ संघर्ष कर रहा हूँ। क्या आप नीचे दिए गए पोस्ट पर एक नज़र डाल सकते हैं। मुझे इस कोड (या अन्य?) की आवश्यकता है ताकि मेरे विषय को ताज़ा किया जा सके ...
मिकी

जवाबों:


149

प्रश्न का सख्ती से उत्तर देने के लिए: अमान्य का उपयोग करें ():

सार्वजनिक शून्य अमान्य () चूंकि: एपीआई स्तर 1

पूरे दृश्य को अमान्य करें। यदि दृश्य दिखाई देता है, तो भविष्य में ऑनड्रॉ (कैनवस) को किसी बिंदु पर बुलाया जाएगा। इसे UI थ्रेड से कहा जाना चाहिए। गैर- UI थ्रेड से कॉल करने के लिए, postInvalidate () को कॉल करें।

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

अब, जब गतिविधि फिर से शुरू होती है, तो यह हर दृश्य को अपनी ओर खींचती है। अमान्य () को कॉल करने की आवश्यकता नहीं होनी चाहिए। विषय को लागू करने के लिए, सुनिश्चित करें कि आप इसे किसी भी दृश्य के आने से पहले, अर्थात, पहले करेंsetContentView(R.layout.mainscreen);

सार्वजनिक शून्य सेटथीम (इंट रेज) चूंकि: एपीआई स्तर 1

इस संदर्भ के लिए आधार विषय निर्धारित करें। ध्यान दें कि यह किसी भी विचार को कॉन्सेप्ट में इंस्टेंट किए जाने से पहले कॉल किया जाना चाहिए (उदाहरण के लिए सेटकॉन्टेंट व्यू (व्यू) या इनफ़्लो (इंट, व्यूग्रुप) को कॉल करने से पहले)।

एपीआई डॉक्टर संदर्भ यहाँ है: http://developer.android.com/reference/android/view/ContextThemeWrapper.html#setTheme%28int%29

चूंकि onDraw () मेथड पहले से इंस्टेंट व्यूज पर काम करता है, setTheme काम नहीं करेगा। मुझे खुद थीम के साथ कोई अनुभव नहीं है, लेकिन दो वैकल्पिक विकल्प जो मैं सोच सकता हूं:

  1. इसके बजाय onCreate () में setTheme को कॉल करें
  2. redo setContentView (R.layout.mainscreen); सभी लेआउट को बहाल करने के लिए मजबूर करना।

धन्यवाद ! यह ठीक चलता है, लेकिन मुझे वह नहीं दिखता जिसकी मुझे उम्मीद थी। आपके कोड को चलाने से पहले मैं Activ.setTheme (newtheme) चलाता हूं, लेकिन इस अमान्य () कॉल से विषय बदलने का कारण नहीं बनता है (जैसे डार्क से लाइट तक)। क्या अमान्य () होना चाहिए?
मिकीआर

@ मिक्की नहीं, यह नहीं होना चाहिए। मेरे अद्यतन उत्तर की जाँच करें। यदि वे दो विकल्प काम नहीं करते हैं, तो आपको अपनी गतिविधि को फिर से शुरू करना होगा।
अलीदाम

विकल्प (1) काम करता है। मेरा ऐप सही विषय के साथ शुरू होगा, लेकिन अगर मैं इसे चलाने के दौरान बदल देता हूं, तो मुझे अपना ऐप फिर से शुरू करना होगा ताकि ऑनक्रिएट () फिर से कहा जाए।
मिकी

विकल्प (2) वह मार्ग है जिसे मैं लेना चाहता था। इसलिए, जब विषय को चलते समय बदल दिया जाता है, तो मैं onRestart () को ऐसा करना चाहता था: - setTheme (getPreferenceTheme ()); और setContentView (R.layout.main); लेकिन इससे मेरा विषय नहीं बदलता। मुझे काम करने का यह दूसरा विकल्प नहीं मिल सकता ...?!
मिकी

मैंने समझा कि विकल्प (2) प्राप्त करने के लिए मुझे 'पदानुक्रम को फिर से बढ़ाने' की आवश्यकता है। मैंने इसे प्राप्त करने के लिए विभिन्न चीजों की कोशिश की है, लेकिन मुझे वास्तव में यह सुनिश्चित नहीं है कि इसका क्या अर्थ है और न ही यह कैसे करना है।
मिकी

41

प्रयत्न getWindow().getDecorView().findViewById(android.R.id.content).invalidate();


3
धन्यवाद ! एक ही जवाब मैंने अलएडम के ऊपर पोस्ट किया। यह अमान्य () गतिविधि विषय को ताज़ा करने का कारण नहीं बनता है जो मुझे चाहिए।
मिकी

36

कोशिश करें recreate()कि यह गतिविधि फिर से पैदा हो।


4
मैंने इस धागे में सभी विकल्पों की कोशिश की, और यह एकमात्र ऐसा है जिसने कम से कम अवांछित दुष्प्रभावों के साथ काम किया है।
स्वोबी

1
क्या होगा अगर मुझे onResumeविधि में ऐसा करने की आवश्यकता है । इससे मुझे इनफिनट लूप मिलता है: /
कामिल विटकोव्स्की

जब तक आपको वास्तव में आवश्यकता न हो, तब तक मैं इसका उपयोग करने की सलाह नहीं देता। आप अनंत लूप से बचने के लिए साझा प्राथमिकताओं में कुछ ध्वज को बचा सकते हैं।
मोहनद ALKHOULI

यह काम करता है लेकिन मैं इसे वास्तविक उत्पादन मोड ऐप में उपयोग करने की अनुशंसा नहीं करूंगा। मुझे केवल डिबग मोड के लिए इसकी आवश्यकता थी इसलिए संपूर्ण UI रीफ्रेशिंग का साइड इफेक्ट महत्वपूर्ण नहीं है।
ड्रोरसन

31

उपाय:

दोस्तों मैं अपने समाधान के सभी की कोशिश की लेकिन वे मेरे लिए काम नहीं किया था, मैं सेट करने के लिए है setVisibility को EditText की दिखाई है और इस EditText में तो दिखाई देना चाहिए scrollview , लेकिन मैं जड़ दृश्य ताज़ा करने के लिए प्रभावी करने के लिए असमर्थ था। मैंने अपनी समस्या को हल किया, जब मुझे दृश्य को ताज़ा करने की आवश्यकता होती है, इसलिए मैंने स्क्रॉल दृश्यता को GONE में बदल दिया और फिर प्रभावी होने के लिए इसे फिर से सेट किया और मेरे लिए यह काम किया। यह सटीक समाधान नहीं है, लेकिन यह केवल काम किया है।

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

2
@ मिक्की कृपया एक उत्तर स्वीकार करें, ताकि लोग आसानी से समाधान पा सकें
नवेद अहमद

वाह .. मैं भी सभी प्रस्तावित sollutions की कोशिश की, लेकिन यह केवल एक ही काम करने लगता है, लेकिन यह भयानक की तरह है ...
Rik van Velzen

मुझे नहीं पता कि क्यों @ मिक्की इस जवाब को स्वीकार नहीं कर रहा है
नवेद अहमद

1
@NaveedAhmad धन्यवाद! सब करने के 4 घंटे के बाद मैं यह काम कर सकता था।
कोडेल्यूस

10

मूल लेआउट पर कॉलिंग invalidate()या postInvalidate()स्पष्ट रूप से यह गारंटी नहीं है कि बच्चों के विचारों को फिर से तैयार किया जाएगा। मेरे विशिष्ट मामले में, मेरा रूट लेआउट एक TableLayout था और इसमें TableRow और TextView के कई बच्चे थे। कॉलिंग postInvalidate(), requestLayout()या भीforceLayout()मूल TableLayout ऑब्जेक्ट पर कि लेआउट में किसी भी TextViews को चालू करने का कारण नहीं था।

इसलिए, मैंने जो किया, वह उन टेक्स्टव्यू की खोज करने वाले लेआउट की पुनरावृत्ति कर रहा था और फिर postInvalidate()उन टेक्स्टव्यू ऑब्जेक्ट्स में से प्रत्येक पर कॉल कर रहा था ।

कोड GitHub पर पाया जा सकता है: https://github.com/jkincali/Android-LinearLayout-Parser


9

अन्यथा आप यह भी कोशिश कर सकते हैं-

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

4
इसके लिए धन्यवाद ! लेकिन, इसने मेरे (टेक्स्टव्यू, बटन आदि) के सभी दृश्यों को हटा दिया, लेकिन उन्हें फिर से नहीं खींचा - मेरी स्क्रीन रिक्त रही ...
मिकी

आपको अपने दृश्य को ताज़ा करने की आवश्यकता है, फिर आपको ड्रॉ फ़ंक्शन को फिर से कॉल करने की आवश्यकता है। पिछले दृश्य को साफ करने के बाद।
दत्त कुंडे

4

बस अपने कंटेंट व्यू को ऑनरेसम में सेट करें

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

मुझे भी यह समस्या हो रही थी, लेकिन फरहान के नेतृत्व का अनुसरण करते हुए setContentView()मैंने ऐसा ही किया। setContentView()हालांकि स्वयं का उपयोग करना पर्याप्त नहीं था। मैंने पाया कि मुझे अपने सभी विचारों को जानकारी के साथ फिर से जोड़ना था। इसे ठीक करने के लिए मैंने बस उस कोड को दूसरी विधि से निकाला (मैंने इसे बिल्ड कहा) और मेरी onCreateविधि में मैं बस उस बिल्ड को कॉल करता हूं। अब जब भी मेरी घटना होती है कि मैं अपनी गतिविधि को "रिफ्रेश" करना चाहता हूं, तो मैं सिर्फ कॉल बिल्ड करता हूं, इसे नई जानकारी दें (जो मैं बनाने के लिए मापदंडों के रूप में पास करता हूं) और मेरे पास एक ताज़ा गतिविधि है।


2

यह एक ज्ञात बग प्रतीत होता है ।


जब मैं अपनी गतिविधि (कॉल समाप्त) (और फिर प्रारंभता ()) को पुनः आरंभ करता हूं, तो setTheme काम करता है। मैं सिर्फ अपनी गतिविधि को फिर से शुरू किए बिना थीम को ताज़ा करने के लिए इसे प्राप्त नहीं कर सकता ...
मिकी

0

मुझे नहीं पता कि यह सुरक्षित है या नहीं, लेकिन यह मेरे लिए काम करता है। मैं थोड़े खुद इस समस्या में भाग गया और कोशिश की invalidate()और requestLayout()कोई फायदा नहीं हुआ। इसलिए मैंने बस अपने onCreate(null)सभी को फिर से बुलाया और यह काम किया। यदि यह असुरक्षित है तो कृपया मुझे बताएं। उम्मीद है कि इससे वहां किसी को मदद मिलेगी।


आप saveInstanceState को अशक्त करने के लिए सेट कर रहे हैं जिससे अप्रत्याशित व्यवहार हो सकता है। अधिक जानकारी के लिए: stackoverflow.com/questions/15115975/…
फिलिप 13

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

व्यूग्रुप का विस्तार करने के लिए, आपको केवल विधि का उपयोग करने की आवश्यकता है removeAllViews()

बस इस तरह (यदि आपके पास व्यूग्रुप कहा जाता है myElement):

myElement.removeAllViews()



-8

केवल इरादे का उपयोग करते हुए गतिविधि को फिर से कॉल करें। उदाहरण के लिए MainActivity के लेआउट को ताज़ा करने के लिए, इस तरह करें:

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

2
यह बदसूरत है! जब आप ऐसा करते हैं, तो आप स्टैक पर एक नई गतिविधि जोड़ते हैं, इसलिए, जब आप बैक बटन दबाते हैं, तो आप उसी गतिविधि पर वापस जाते हैं।
डैनियल बेल्ट्रामी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.