cav*_*ega 17 android android-actionbar
我有一个主/详细布局的应用程序(1个活动,1个ListView片段和1个细节片段).当用户单击ListView中的项目时,片段事务会在右窗格中实例化一个详细信息片段,其中包含与该项目对应的信息.当显示细节片段时,我隐藏了初始操作栏按钮/项目并显示3个新的AB项目(完成/删除/取消).用户可以通过按后退按钮或按下3 AB项中的一个来清理右窗格并返回初始UI状态.
我遇到的问题是,当用户选择应用程序的主页图标(即"向上导航")时,活动会重新加载(即表示活动正在启动的动画可以被视为操作栏和UI已被重绘).只有在按下应用程序主页图标时才会出现此问题.如果用户按下后退按钮或取消/完成/删除操作栏按钮,则只需从右窗格中删除片段,UI将返回初始状态而不会"重新加载".
活动的XML布局如下(在LinearLayout内部;美化隐藏该行):
<fragment class="*.*.*.ListFragment"
android:id="@+id/titles" android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
<FrameLayout android:id="@+id/details" android:layout_weight="2"
android:layout_width="0px"
android:layout_height="match_parent" />
Run Code Online (Sandbox Code Playgroud)
DetailsFragement在其onCreate方法中具有actionBar.setDisplayHomeAsUpEnabled语句:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
ActionBar actionBar = getSherlockActivity().getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
Run Code Online (Sandbox Code Playgroud)
对于ListView片段和Detail片段,onCreateOptionsMenu()和onOptionsItemSelected()方法都在片段中实现.在Details片段的代码下面:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.edit_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// some variable statements...
switch (item.getItemId()) {
case android.R.id.home:
//Toast.makeText(getSherlockActivity(), "Tapped home", Toast.LENGTH_SHORT).show();
onHomeSelectedListener.onHomeSelected();
return true;
case R.id.menu_edit_item_done:
editedTask.setTitle(editedTaskTitle);
onTaskEditedListener.onTaskEdited(editedTask, UPDATE_TASK, true);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Run Code Online (Sandbox Code Playgroud)
在主机活动中,我实现了onHomeSelectedListner来处理app home图标按下(即"向上导航":
public void onHomeSelected(){
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
TaskFragment taskFragment = (TaskFragment)getSupportFragmentManager().findFragmentById(R.id.details);
ft.remove(taskFragment);
ft.commit();
manager.popBackStack();
}
Run Code Online (Sandbox Code Playgroud)
负责处理所有其他操作栏按钮(即完成/删除/取消)的活动的监听器是onTaskEditedListener,除了处理某些数据的其他代码之外,它具有上面显示的相同片段事务.
更新(1/24) 基于tyczj和straya反馈,我将log语句放在onCreate(),onResume(),onPause()的活动中,以确定onHomeSelected和onTaskEdited监听器之间的差异.我能够确认在"向上导航"事件(即onHomeSelected)onPause()期间,调用onCreate()和onResume().而在onTaskEdited调用期间(即后退按钮或完成/删除/取消按下),这些事件都不会被调用.
更新(1/25) 根据Mark Murphy的建议,我在"case android.R.id.home"语句中注释了onHomeSelected方法调用,只是为了看看Activity会做什么.我们的想法是应用程序什么都不做,因为没有声明.事实证明并非如此.即使没有调用侦听器方法(即删除片段),也会重新启动活动并从片段容器中删除详细信息片段.
更新(2/28) 我通过禁用窗口动画(我自己的答案中突出显示)暂时解决了我的主要活动重新启动的事实.但是,通过进一步测试,我发现了一个错误.感谢Wolfram Rittmeyer的示例代码,我能够找出在上导航期间我的活动重启(主/详细单一布局)的真正原因:1)虽然我正在使用这个"onHomeSelectedListener"来正确删除片段从后台堆栈,我仍然在ListView片段的onOptionsItemSelected中有一些残余代码,它们创建了一个新的意图来启动托管活动.这就是为什么按下应用程序的主页图标重新启动活动.2)在我的最终实现中(在我自己的答案中显示),我删除了活动中的onHomeSelectedListener并替换了ListView的onOptionsItemSelected中的startActivity意图(即违规代码),以使用最初在onHomeSelectedListener中的片段删除+ popBackStack代码.
经过大量的研究和探索,结果证明我的活动在主导/详细配置的"向上导航"期间重新启动的唯一原因是因为我在ListView片段的onOptionsItemSelected中留下了一些代码,该代码创建了另外一个启动主要活动的意图到其他地方我的完整片段交易代码.下面是最后的实现,我通过它"导航"在手机(多个活动)和平板电脑(单个活动/多窗格)配置上正常工作.感谢Wolfram Rittmeyer在他的代码中提供了几个提示(评论部分中的链接),这有助于我查明我的问题!
主要活动:托管片段并执行一些其他特定于应用程序的操作
ListView片段:处理表格配置中的"向上导航"
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if(mDualPane){
FragmentManager manager = getSherlockActivity().getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
DetailFragment detailFragment = (DetailFragment)manager.findFragmentById(R.id.details);
ft.remove(detailFragment);
ft.commit();
manager.popBackStack();
getSherlockActivity().getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSherlockActivity().getSupportActionBar().setHomeButtonEnabled(false);
}
return true;
// Other case statements...
default:
return super.onOptionsItemSelected(item);
}
}
Run Code Online (Sandbox Code Playgroud)
详细信息片段:处理电话配置中的导航
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// Sets "up navigation" for both phone/tablet configurations
ActionBar actionBar = getSherlockActivity().getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if(!mDualPane){
Intent parentActivityIntent = new Intent(getSherlockActivity(), MainActivity.class);
parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
getSherlockActivity().finish();
}
return true;
// Other case statements...
default:
return super.onOptionsItemSelected(item);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30748 次 |
| 最近记录: |