Как принудительно обновить весь макет View?
Я хочу принудительно перерисовать / обновить основной вид ресурсов макета, скажем, методом Activity.onResume(). Как я могу это сделать?
Под основным представлением макета я подразумеваю тот ("R.layout.mainscreen" ниже), который вызывается в моем Activity.onCreate(), например:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainscreen);
}
20 ответов
Чтобы строго ответить на вопрос: используйте invalidate ():
public void invalidate () Так как: Уровень API 1
Опровергнуть весь взгляд. Если представление является видимым, onDraw (Canvas) будет вызван в какой-то момент в будущем. Это должно быть вызвано из потока пользовательского интерфейса. Для вызова из потока, не являющегося пользовательским интерфейсом, вызовите postInvalidate ().
ViewGroup vg = findViewById (R.id.mainLayout);
vg.invalidate();
Теперь, когда действие возобновляется, он заставляет каждый вид рисовать сам. Не нужно вызывать invalidate (). Чтобы применить тему, убедитесь, что вы делаете это до того, как будет нарисовано любое представление, т.е. setContentView(R.layout.mainscreen);
public void setTheme (int остаток) С: API Уровень 1
Установите базовую тему для этого контекста. Обратите внимание, что это следует вызывать до того, как будут созданы какие-либо представления в контексте (например, перед вызовом setContentView (View) или inflate (int, ViewGroup)).
Ссылка на документацию по API находится здесь: http://developer.android.com/reference/android/view/ContextThemeWrapper.html
Поскольку метод onDraw() работает с уже созданными экземплярами Views, setTheme работать не будет. У меня нет опыта работы с темами, но я могу подумать о двух альтернативных вариантах:
- вместо этого вызовите setTheme в onCreate(), или
- повторить setContentView (R.layout.mainscreen); заставить восстановить все макет.
Пытаться getWindow().getDecorView().findViewById(android.R.id.content).invalidate();
Пытаться recreate()
это приведет к воссозданию этого занятия.
Решение:
Ребята, я перепробовал все ваши Решения, но они не сработали для меня, я должен установить для setVisibility EditText значение VISIBLE, и этот EditText должен быть виден тогда в ScrollView, но я не смог обновить представление root для вступления в силу. Я решил свою проблему, когда мне нужно обновить вид, поэтому я изменил видимость ScrollView на GONE, а затем снова установил его на VISIBLE, чтобы он вступил в силу, и это сработало для меня. Это не точное решение, но оно только сработало.
private void refreshView(){
mScrollView.setVisibility(View.GONE);
mScrollView.setVisibility(View.VISIBLE);
}
Призвание invalidate()
или же postInvalidate()
на корневой макет, очевидно, не гарантирует, что дочерние представления будут перерисованы. В моем конкретном случае мой корневой макет был TableLayout и имел несколько дочерних классов класса TableRow и TextView. призвание postInvalidate()
, или же requestLayout()
или даже forceLayout()
в корневом объекте TableLayout не было вызвано перерисовывание текстовых представлений в макете.
Итак, я закончил рекурсивным разбором макета, ища эти TextViews и затем вызвал postInvalidate()
на каждом из этих объектов TextView.
Код можно найти на GitHub: https://github.com/jkincali/Android-LinearLayout-Parser
В противном случае вы можете попробовать это также
ViewGroup vg = (ViewGroup) findViewById (R.id.videoTitleTxtView);
vg.removeAllViews();
vg.refreshDrawableState();
Просто установите ваш контент в onresume
setContentView (R.layout.yourview) внутри onResume..
Пример:
@Override
public void onResume(){
super.onResume();
setContentView(R.layout.activity_main);
postIncomeTotals();
}
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);
Это позволяет перезагрузить с изменениями темы и скрывает анимацию.
Попробуйте этот обходной путь для проблемы с темой:
@Override
public void onBackPressed() {
NavUtils.navigateUpTo(this, new Intent(this,
MyNeedToBeRefreshed.class));
}
У меня была эта проблема, но следуя указаниям Фархана по использованию setContentView()
Я так и сделал. с помощью setContentView()
само по себе было недостаточно, однако. Я обнаружил, что должен был заселить все свои взгляды информацией. Чтобы исправить это, я просто вытащил весь этот код в другой метод (я назвал его build) и в моем onCreate
метод, который я просто называю этой сборкой. Теперь, когда происходит мое событие, я хочу, чтобы моя деятельность "обновлялась", я просто вызываю сборку, сообщаю ей новую информацию (которую я передаю в качестве параметров для сборки), и у меня появляется обновленное действие.
Так я обновлял свой макет
Intent intent = getIntent();
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);
Я не знаю, безопасно это или нет, но это сработало для меня. Я сам наткнулся на эту проблему и попытался invalidate()
а также requestLayout()
но безрезультатно. Я просто позвонил onCreate(null)
все снова и снова сработало. Если это небезопасно, пожалуйста, дайте мне знать. Надеюсь, это поможет кому-то там.
Если вы собираетесь создать собственное представление, убедитесь, что оно расширяет SurfaceView , после чего вы можете перерисовать его с помощью метода
getHolder().lockCanvas()
. Вот пример:
Canvas c = getHolder().lockCanvas();
c.drawText("Text", x, y, paint);
getHolder().unlockCanvasAndPost(c);
parent.invalidate() не будет работать без parent.requestLayout(). Итак, используйте
parent.invalidate()
container.requestLayout()
ответ: Вы можете обновить и заново создать мероприятие и сохранить данные, отправив их с помощью намерения.
public void refresh() {
Intent intent = getIntent();
intent.putExtra("extra_id",details);
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
overridePendingTransition(0, 0);
startActivity(intent);
}
и получить его в onCreate
details=getIntent().getStringExtra("extra_id")
Не уверен, что это хороший подход, но я просто каждый раз так называю:
setContentView(R.layout.mainscreen);
Чтобы очистить представление, расширяющее ViewGroup, вам просто нужно использовать метод removeAllViews()
Точно так же (если у вас есть ViewGroup с именем myElement
):
myElement.removeAllViews()
Просто снова вызовите само действие, используя намерение. Например, чтобы обновить макет MainActivity, сделайте так:
startActivity(new Intent(MainActivity.this, MainActivity.class));