How to force an entire layout View refresh?
To strictly answer the question: Use invalidate():
public void invalidate () Since: API Level 1
Invalidate the whole view. If the view is visible, onDraw(Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().
ViewGroup vg = findViewById (R.id.mainLayout);
vg.invalidate();
Now, when the Activity resumes, it makes every View to draw itself. No call to invalidate() should be needed. To apply the theme, make sure you do it before any View is drawn, i.e., before setContentView(R.layout.mainscreen);
public void setTheme (int resid) Since: API Level 1
Set the base theme for this context. Note that this should be called before any views are instantiated in the Context (for example before calling setContentView(View) or inflate(int, ViewGroup)).
The API doc reference is here: http://developer.android.com/reference/android/view/ContextThemeWrapper.html#setTheme%28int%29
Since the onDraw() method works on already instantiated Views, setTheme will not work. I have no experience with themes myself, but two alternative options I can think are:
- call setTheme in onCreate() instead, or
- redo setContentView (R.layout.mainscreen); to force reinstantiate all the layout.
Try getWindow().getDecorView().findViewById(android.R.id.content).invalidate();
Try recreate()
it will cause this Activity to be recreated.
Solution:
Guys I tried all of your Solutions but they did not worked for me, I have to set setVisibility of EditText to VISIBLE and this EditText should be visible then in ScrollView, but I was unable to refresh root view to take effect. I solved my problem, when I need to refresh the view so I changed the ScrollView visibility to GONE and then again set it to VISIBLE to take effect and it worked for me. This is not the exact solution but it only worked.
private void refreshView(){
mScrollView.setVisibility(View.GONE);
mScrollView.setVisibility(View.VISIBLE);
}
Calling invalidate()
or postInvalidate()
on the root layout apparently does NOT guarantee that children views will be redrawn. In my specific case, my root layout was a TableLayout and had several children of class TableRow and TextView. Calling postInvalidate()
, or requestLayout()
or even forceLayout()
on the root TableLayout object did not cause any TextViews in the layout to be redrawn.
So, what I ended up doing was recursively parsing the layout looking for those TextViews and then calling postInvalidate()
on each of those TextView objects.
The code can be found on GitHub: https://github.com/jkincali/Android-LinearLayout-Parser