工具栏不会在操作模式下消失
Toolbar won't disappear in action mode
我正在尝试实现以下功能:当我长按列表项时,将启动操作模式,并且可以删除一个或多个项目。
我从 DocumentsActivity
搜索开始,该搜索会启动带有 ListView 及其项目的片段 DocumentsFragment
。 ListAdapter 是通过Fragment 的onCreate 中的方法调用setListAdapter(this.documentsAdapter)
来初始化和设置的。我在 Fragment:
的 onActivityCreated
中的列表视图上设置了各种侦听器
public void onActivityCreated(Bundle savedInstanceState) {
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
getListView().setItemChecked(position, true);
return true;
}});
getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
((DocumentsActivity)getActivity()).getMenuInflater().inflate(R.menu.documents_context_menu, menu);
return true;
}
});
super.onActivityCreated(savedInstanceState);
}
当长按列表项时,动作模式开始,菜单 documents_context_menu
显示为动作栏。但问题是,操作栏出现在工具栏上方,工具栏不会消失(见图片)。
我试过调用 getSupportActionBar().hide()
或将其设置为空,甚至使用另一个 style/theme。这一切都没有用。有时蓝色工具栏是完全白色的,但仅此而已。
我完全不知道为什么工具栏不会消失。可以给点建议吗?
提前致谢!
_____ 更新 1 _____
这是styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:fitsSystemWindows">true</item>
<item name="colorAccent">@color/darkblue100</item>
<item name="android:actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
<item name="actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
<item name="android:actionMenuTextColor">@color/black</item>
</style>
这就是在 Activity 中设置操作栏的方式:
protected void onCreate(Bundle savedInstanceState) {
handleIntent(getIntent());
requestWindowFeature(5);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_documents);
Toolbar mToolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(mToolbar);
args = getIntent().getExtras();
if (findViewById(R.id.container_documents) != null && savedInstanceState == null) {
showDocumentsFragment();
}
}
正如评论中提供的 link 所指出的,您只需在 AppTheme 样式中添加以下行:
<item name="windowActionModeOverlay">true</item>
只是表示动作模式应该覆盖window内容而不是将其向下推,它告诉你不需要为动作模式保留任何space。
添加:
//Set action mode null after use
public void setNullToActionMode() {
if (mActionMode != null)
mActionMode = null;
}
或者:
//Remove selected selections
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
}
据我浏览你的代码并理解它,你已经完成了你提供的工具栏作为 ActionBar 并使用 .NoActionBar 主题的所有内容,除了根据 Android 开发人员你还应该设置windowActionBar 属性在您的样式中设置为 false。 enter link description here 第二段清除它。
希望对您有所帮助!
所有这些答案都很好你应该尝试它们但你需要的是 ContextualMenu
所以你应该首先将视图添加到 registerForContextMenu()
这样菜单就知道哪些菜单是上下文的然后实现 onCreateContextMenu
你的 Activity
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
然后像这样实现 onContextItemSelected()
:
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit:
editNote(info.id);
return true;
case R.id.delete:
deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
然后您必须对视图执行操作并实施 AbsListView.MultiChoiceModeListener
然后使用 CHOICE_MODE_MULTIPLE_MODAL
参数调用 setChoiceMode()
。像这样:
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.menu_delete:
deleteSelectedItems();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context, menu);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an <code><a href="/reference/android /view/ActionMode.html#invalidate()">invalidate()</a></code> request
return false;
}
});
我所说的所有内容以及更多内容,您可以在 this android developer documentation
中找到
实际上这个问题是由不同的事情引起的。
首先,windowActionBar
设置了true
,还有属性fitsSystemWindows.
我在styles.xml
.[=20=中删除了两行]
然后在activity布局里有属性layout_marginTop="?actionBarSize"
我没看到,一头雾水跟着。但是这个属性需要存在,所以当调用 onCreateActionMode
和 onDestroyActionMode
时,我在方法 onActivityCreated
中处理它。
在那之后,我遇到了列表视图项目消失的自动问题。我通过在 onDestroyActionMode
.
中再次提交我的片段来修复它
public void onActivityCreated(Bundle savedInstanceState) {
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {...}
});
getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
LinearLayout ll = ((DocumentsActivity)getActivity()).findViewById(R.id.container_documents);
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
params.setMargins(0, 0, 0, 0);
ll.setLayoutParams(params);
((DocumentsActivity)getActivity()).getSupportActionBar().hide();
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.documents_context_menu, menu);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
params.setMargins(0, R.attr.actionBarSize, 0, 0);
ll.setLayoutParams(params);
((DocumentsActivity)getActivity()).getSupportActionBar().show();
if (getFragmentManager() != null)
getFragmentManager()
.beginTransaction()
.detach(this)
.attach(this)
.commit();
}
});
super.onActivityCreated(savedInstanceState);
}
在 Kotlin 中,假设您的 Activity
扩展自 AppCompatActivity
您应该获取支持操作栏的实例并调用方法
supportActionBar?.show()
或 supportActionBar?.hide()
如果您使用的是片段,则可以从片段的 activity 实例
访问操作栏
(activity as AppCompatActivity).supportActionBar?.show()
我正在尝试实现以下功能:当我长按列表项时,将启动操作模式,并且可以删除一个或多个项目。
我从 DocumentsActivity
搜索开始,该搜索会启动带有 ListView 及其项目的片段 DocumentsFragment
。 ListAdapter 是通过Fragment 的onCreate 中的方法调用setListAdapter(this.documentsAdapter)
来初始化和设置的。我在 Fragment:
onActivityCreated
中的列表视图上设置了各种侦听器
public void onActivityCreated(Bundle savedInstanceState) {
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
getListView().setItemChecked(position, true);
return true;
}});
getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
((DocumentsActivity)getActivity()).getMenuInflater().inflate(R.menu.documents_context_menu, menu);
return true;
}
});
super.onActivityCreated(savedInstanceState);
}
当长按列表项时,动作模式开始,菜单 documents_context_menu
显示为动作栏。但问题是,操作栏出现在工具栏上方,工具栏不会消失(见图片)。
我试过调用 getSupportActionBar().hide()
或将其设置为空,甚至使用另一个 style/theme。这一切都没有用。有时蓝色工具栏是完全白色的,但仅此而已。
我完全不知道为什么工具栏不会消失。可以给点建议吗?
提前致谢!
_____ 更新 1 _____
这是styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:fitsSystemWindows">true</item>
<item name="colorAccent">@color/darkblue100</item>
<item name="android:actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
<item name="actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
<item name="android:actionMenuTextColor">@color/black</item>
</style>
这就是在 Activity 中设置操作栏的方式:
protected void onCreate(Bundle savedInstanceState) {
handleIntent(getIntent());
requestWindowFeature(5);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_documents);
Toolbar mToolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(mToolbar);
args = getIntent().getExtras();
if (findViewById(R.id.container_documents) != null && savedInstanceState == null) {
showDocumentsFragment();
}
}
正如评论中提供的 link 所指出的,您只需在 AppTheme 样式中添加以下行:
<item name="windowActionModeOverlay">true</item>
只是表示动作模式应该覆盖window内容而不是将其向下推,它告诉你不需要为动作模式保留任何space。
添加:
//Set action mode null after use
public void setNullToActionMode() {
if (mActionMode != null)
mActionMode = null;
}
或者:
//Remove selected selections
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
}
据我浏览你的代码并理解它,你已经完成了你提供的工具栏作为 ActionBar 并使用 .NoActionBar 主题的所有内容,除了根据 Android 开发人员你还应该设置windowActionBar 属性在您的样式中设置为 false。 enter link description here 第二段清除它。
希望对您有所帮助!
所有这些答案都很好你应该尝试它们但你需要的是 ContextualMenu
所以你应该首先将视图添加到 registerForContextMenu()
这样菜单就知道哪些菜单是上下文的然后实现 onCreateContextMenu
你的 Activity
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
然后像这样实现 onContextItemSelected()
:
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit:
editNote(info.id);
return true;
case R.id.delete:
deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
然后您必须对视图执行操作并实施 AbsListView.MultiChoiceModeListener
然后使用 CHOICE_MODE_MULTIPLE_MODAL
参数调用 setChoiceMode()
。像这样:
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.menu_delete:
deleteSelectedItems();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context, menu);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an <code><a href="/reference/android /view/ActionMode.html#invalidate()">invalidate()</a></code> request
return false;
}
});
我所说的所有内容以及更多内容,您可以在 this android developer documentation
中找到实际上这个问题是由不同的事情引起的。
首先,windowActionBar
设置了true
,还有属性fitsSystemWindows.
我在styles.xml
.[=20=中删除了两行]
然后在activity布局里有属性layout_marginTop="?actionBarSize"
我没看到,一头雾水跟着。但是这个属性需要存在,所以当调用 onCreateActionMode
和 onDestroyActionMode
时,我在方法 onActivityCreated
中处理它。
在那之后,我遇到了列表视图项目消失的自动问题。我通过在 onDestroyActionMode
.
public void onActivityCreated(Bundle savedInstanceState) {
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {...}
});
getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
LinearLayout ll = ((DocumentsActivity)getActivity()).findViewById(R.id.container_documents);
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
params.setMargins(0, 0, 0, 0);
ll.setLayoutParams(params);
((DocumentsActivity)getActivity()).getSupportActionBar().hide();
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.documents_context_menu, menu);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
params.setMargins(0, R.attr.actionBarSize, 0, 0);
ll.setLayoutParams(params);
((DocumentsActivity)getActivity()).getSupportActionBar().show();
if (getFragmentManager() != null)
getFragmentManager()
.beginTransaction()
.detach(this)
.attach(this)
.commit();
}
});
super.onActivityCreated(savedInstanceState);
}
在 Kotlin 中,假设您的 Activity
扩展自 AppCompatActivity
您应该获取支持操作栏的实例并调用方法
supportActionBar?.show()
或supportActionBar?.hide()
如果您使用的是片段,则可以从片段的 activity 实例
访问操作栏(activity as AppCompatActivity).supportActionBar?.show()