如何将ActionBar按钮设为返回而非向上导航以避免页面重载?
我明白你遇到的困扰:物理返回键能回到原来的AlbumListActivity且不重载数据,但ActionBar的返回按钮却会重新加载列表。这其实是因为Android里**Back(返回)和Up(向上导航)**的默认处理逻辑有差异,哪怕你的AlbumDetailActivity不会被其他应用打开,默认的Up导航还是可能创建新的Activity实例。
为什么会这样?
物理返回键是严格按照用户的操作历史(任务栈)来回溯,直接弹出当前的AlbumDetailActivity,回到栈中已经存在的AlbumListActivity实例,所以不会触发重新加载。而默认的ActionBar返回按钮(Up),如果没正确配置,会通过Intent启动父Activity(AlbumListActivity),默认会创建新的实例,导致重新走onCreate方法加载数据。
两种快速解决方法
方法1:让Up按钮直接复用物理返回键的逻辑
最简单的方式就是在AlbumDetailActivity里重写onOptionsItemSelected方法,当点击ActionBar的Home按钮时,直接调用物理返回键的处理逻辑:
@Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { // 直接触发物理返回键的行为 onBackPressed(); return true; } return super.onOptionsItemSelected(item); }
这样不管什么情况,Up按钮和物理返回键的行为完全一致,都会回到原来的AlbumListActivity实例,不会重新加载数据。
方法2:遵循Android导航规范配置父Activity
如果你想更贴合Android的导航设计规范,可以按以下步骤操作:
在Manifest中配置父Activity关系
打开AndroidManifest.xml,给AlbumDetailActivity添加父Activity的声明:<activity android:name=".AlbumDetailActivity" android:parentActivityName=".AlbumListActivity"> <!-- 兼容Android 4.0及以下版本 --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".AlbumListActivity" /> </activity>正确处理Up导航的点击事件
在AlbumDetailActivity的onOptionsItemSelected中,使用NavUtils来处理向上导航,确保复用栈中已有的父Activity实例:@Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); }这个方法的前提是AlbumDetailActivity是从同一个任务栈的AlbumListActivity启动的(你的场景完全符合),它会直接回到栈中已存在的AlbumListActivity实例,不会创建新的。
额外的优化建议
为了避免即使意外创建新实例也不会重复加载数据,你可以在AlbumListActivity的onCreate方法中,只在第一次创建时加载数据:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_album_list); // 只有当Activity是第一次创建(savedInstanceState为空)时才加载数据 if (savedInstanceState == null) { loadAlbumsFromNetwork(); } }
这样双重保障,不管是哪种返回方式,都不会重复加载数据啦。
内容的提问来源于stack exchange,提问作者Abdurakhmon

