Как я могу вернуться к родительской деятельности правильно?
у меня есть 2 действия (A и B) в моем приложении для android, и я использую намерение перейти от действия A к действию B. использование parent_activity включено:
<activity
android:name=".B"
android:label="B" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app_name.A" />
</activity>
Я также использую тему, которая обеспечивает кнопку вверх.
поэтому после того, как я вызвал activity B, я могу использовать кнопку UP, чтобы вернуться к activity A. проблема в том, что приложение, похоже, вызывает onCreate ()-функция активности a снова, и это не то поведение, которое мне нужно. Мне нужно действие A, чтобы выглядеть так же, как это выглядело до того, как я назвал действие B.
есть ли способ достичь этого?
спасибо заранее
EDIT:
Я не писал никакого кода для запуска activity B из activity A. Я думаю, что он автоматически генерируется eclipse.
класс B выглядит так:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
16 ответов:
вы объявили активность A со стандартом
launchMode
в манифесте Android. Согласно документация, что означает следующее:система всегда создает новый экземпляр активности в целевой задача и направляет намерение к ней.
поэтому система вынуждена воссоздать действие A (т. е. вызов
onCreate
) даже если стек задач обрабатывается правильно.чтобы решить эту проблему, вам нужно измените манифест, добавив в объявление действия a следующий атрибут:
android:launchMode="singleTop"
Примечание: вызов
finish()
(как было предложено в качестве решения раньше) работает только когда вы абсолютно точно что экземпляр activity B, который вы завершаете, живет поверх экземпляра activity A. в более сложных рабочих процессах (например, запуск activity B из уведомления) это может быть не так, и вам нужно правильно запустить упражнение а от В.
Обновленный Ответ: Вверх По Дизайну Навигации
вы должны объявить, какое действие является подходящим родителем для каждого действия. Это позволяет системе упростить шаблоны навигации, такие как Up, поскольку система может определить логическую родительскую активность из файла манифеста.
поэтому для этого вам нужно объявить свою родительскую активность в теге Activity с атрибутом
android:parentActivityName
например,
<!-- The main/home activity (it has no parent activity) --> <activity android:name="com.example.app_name.A" ...> ... </activity> <!-- A child of the main activity --> <activity android:name=".B" android:label="B" android:parentActivityName="com.example.app_name.A" > <!-- Parent activity meta-data to support 4.0 and lower --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.app_name.A" /> </activity>
С родительской активностью, объявленной таким образом, вы можете перейти к соответствующему родителю, как показано ниже,
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); }
поэтому, когда вы называете
NavUtils.navigateUpFromSameTask(this);
этот метод завершает текущую операцию и запускает (или возобновляет) соответствующую родительскую операцию. Если целевое родительское действие находится в заднем стеке задачи, оно переносится вперед, как определеноFLAG_ACTIVITY_CLEAR_TOP
.и для отображения кнопки вы должны объявить
setDisplayHomeAsUpEnabled():
@Override public void onCreate(Bundle savedInstanceState) { ... getActionBar().setDisplayHomeAsUpEnabled(true); }
старый ответ: (без навигации вверх, навигация по умолчанию назад)
это произойдет только в том случае, если вы снова начинаете действие A С действия B.
используя
startActivity()
.вместо этого из действия a начните действие B с помощью
startActivityForResult()
и переопределитьonActivtyResult()
в работе А.теперь в действии B просто позвоните
finish()
на кнопку Вверх. Итак, теперь вы направлены на деятельность AonActivityResult()
без создания снова деятельности..
у меня была почти такая же настройка, приводящая к тому же нежелательному поведению. Для меня это работало: добавление следующего атрибута к действию A в
Manifest.xml
Мои приложения:android:launchMode="singleTask"
посмотреть в этой статье для более подробного объяснения.
хотя старый вопрос, вот еще одно (имхо самое чистое и лучшее) решение, так как все предыдущие ответы не работали для меня, так как я deeplinked Activity B С виджет.
public void navigateUp() { final Intent upIntent = NavUtils.getParentActivityIntent(this); if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) { Log.v(logTag, "Recreate back stack"); TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities(); } else { NavUtils.navigateUpTo(this, upIntent); } }
[https://stackoverflow.com/a/31350642/570168 ]
но также см.: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android
лучший способ достичь этого-использовать две вещи: звоните:
NavUtils.navigateUpFromSameTask(this);
теперь, чтобы это работало, вам нужно иметь состояние файла манифеста, что действие A родитель Б. активность родительской активности ничего не нужно. В версии 4 и выше вы получите хорошую стрелку назад без дополнительных усилий (это можно сделать и на более низких версиях с небольшим кодом, я поставлю его ниже) Вы можете установить эти данные на вкладке манифест->приложение в графическом интерфейсе (прокрутите вниз до имя родительского действия, и положить его вручную)
поддержки узел:
Если вы хотите поддерживать версию ниже версии 4, Вам также необходимо включить метаданные. щелкните правой кнопкой мыши на активности, добавить - >метаданные, имя =android.поддержка.PARENT_ACTIVITY и value = your.full.activity.name
чтобы получить хорошую стрелку в более низких версиях, а также:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
обратите внимание, что вам понадобится поддержка библиотеки версии 7, чтобы все это работало, но это того стоит это!
пробовал
android:launchMode="singleTask"
, но это не помогло. Работал для меня с помощьюandroid:launchMode="singleInstance"
добавление к ответу @LorenCK, изменить
NavUtils.navigateUpFromSameTask(this);
в код ниже, если ваша деятельность может быть инициирована из другой деятельности, и это может стать частью задачи, запущенной каким-либо другим приложением
Intent upIntent = NavUtils.getParentActivityIntent(this); if (NavUtils.shouldUpRecreateTask(this, upIntent)) { TaskStackBuilder.create(this) .addNextIntentWithParentStack(upIntent) .startActivities(); } else { NavUtils.navigateUpTo(this, upIntent); }
это запустит новую задачу и запустит родительскую активность вашей активности, которую вы можете определить в манифесте, как показано ниже версии min SDK
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.app_name.A" />
или через
parentActivityName
если > 15
то, что сработало для меня, добавляло:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: onBackPressed(); return true; default: return super.onOptionsItemSelected(item); } } @Override public void onBackPressed() { finish(); }
до
TheRelevantActivity.java
и теперь он работает, как ожидалосьи да, не забудьте добавить:
getSupportActionbar.setDisplayHomeAsUpEnabled(true);
наonCreate()
метод
У меня была аналогичная проблема с использованием android 5.0 с плохим именем родительской активности
<activity android:name=".DisplayMessageActivity" android:label="@string/title_activity_display_message" android:parentActivityName=".MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myfirstapp.MainActivity" /> </activity>
Я удалил ком.образец.myfirstapp от имени родительского действия, и он работал правильно
добавьте в свой манифест активности информацию с атрибутом
android:launchMode="singleTask"
работает хорошо для меня
в классе Java: -
toolbar = (Toolbar) findViewById(R.id.apptool_bar); setSupportActionBar(toolbar); getSupportActionBar().setTitle("Snapdeal"); getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
В Манифесте :-
<activity android:name=".SubActivity" android:label="@string/title_activity_sub" android:theme="@style/AppTheme" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"></meta-data> </activity>
Это поможет вам
попробуйте это:
Intent intent; @Override public void onCreate(Bundle savedInstanceState) { intent = getIntent(); super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); getActionBar().setDisplayHomeAsUpEnabled(true); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_b, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: NavUtils.navigateUpTo(this,intent); return true; } return super.onOptionsItemSelected(item); }
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: finish(); return true; } return super.onOptionsItemSelected(item);
Как назад нажмите
вход в мой манифест и добавление
android:launchMode="singleTop"
активность сделал трюк для меня.это специально решило мою проблему, потому что я не хотел, чтобы Android создавал новый экземпляр предыдущей активности после нажатия
Up
кнопка на панели инструментов-вместо этого я хотел использовать существующий экземпляр предыдущего действия, когда я поднялся по иерархии навигации.ссылки: android: launchMode
попробуйте это решение использовать NavUtils.navigateUpFromSameTask (this); в дочернем действии: https://stackoverflow.com/a/49980835/7308789