除了传统的android.view.ActionMode
之外,我正在尝试将android.support.v7.widget.Toolbar
与新android.app.ActionBar
一起使用。我可以用以下方式显示它:
toolbar.startActionMode(callback);
问题是ActionMode
显示在ActionBar
上方,而不是Toolbar
上方。有没有办法改变它?
我试图在我的主题中设置以下内容,但它似乎没有改变任何内容:
<item name="windowActionModeOverlay">true</item>
答案 0 :(得分:72)
由于您使用的是
Toolbar
,我还假设您使用的是AppCompatActivity
ActionBar
并已将内置的Toolbar
替换为 您的自定义setSupportActionBar(toolbar);
使用import android.support.v7.view.ActionMode;
首先确保您导入正确的命名空间。
import android.view.ActionMode;
而不是
_actionMode = startSupportActionMode(this);
然后使用
_actionMode = startActionMode(this);
而不是
{{1}}
答案 1 :(得分:60)
不要在您的活动上启动它,而是在工具栏上启动它。在你的活动中:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.startActionMode(mActionModeCallback)
你必须使用
<item name="windowActionModeOverlay">true</item>
在你的主题中,如安德烈所说。
答案 2 :(得分:36)
在你的主题中试试这个:
<item name="windowActionModeOverlay">true</item>
答案 3 :(得分:2)
找到您的AndroidManifest.xml,然后在您的应用程序或Activity主题中添加以下代码
<item name="windowActionModeOverlay">true</item>
类似:
<style name="WorkTimeListTheme" parent="AppTheme.NoActionBar">
<item name="windowActionModeOverlay">true</item>
<item name="actionModeBackground">@color/theme_primary</item>
</style>
答案 4 :(得分:2)
我认为人们不清楚的一件事是线
<item name="windowActionModeOverlay">true</item>
放置在基本主题中,即AppTheme而不是AppTheme.NoActionBar
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="transparent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
答案 5 :(得分:1)
这是我的解决方案。
在 ActionMode.Callback 的 onCreateActionMode 方法中,我添加了这个:
StandaloneActionMode standaloneActionMode = (StandaloneActionMode) actionMode;
Field mContextView;
try {
mContextView = StandaloneActionMode.class.getDeclaredField("mContextView");
mContextView.setAccessible(true);
View contextView = (View) mContextView.get(standaloneActionMode);
MarginLayoutParams params = (MarginLayoutParams) contextView.getLayoutParams();
params.topMargin = mToolbar.getTop();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
它对我有用。
答案 6 :(得分:1)
我已经尝试了上面的所有方法,但它仍然无法正常工作。然后,我尝试了以下方法:
private class ActionModeCallback implements ActionMode.Callback {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
actionMode.getMenuInflater().inflate(R.menu.note_find_action, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
((AppCompatActivity) getActivity()).getSupportActionBar().hide();
return false;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
((AppCompatActivity) getActivity()).getSupportActionBar().show();
}
}
这里,我使用了支持库的动作模式和startSupportActionMode方法。与此同时,我也尝试修改给定活动的主题。当然,它不起作用。所以,如果你真的没有更好的选择,你可以试试这个。
就在最近,我发现我使用了Colorful框架来启用我的应用程序的多个主题,这将改变代码中的主题。当我尝试修改此框架中的样式时,它可以正常工作。
希望它有效。
答案 7 :(得分:1)
因此,经过几天的处理之后,我终于使它工作了。 我想总结一下我所做的。
注意:这是使用
Toolbar
替换ActionBar
中默认的AppCompatActivity
的解决方案。
AppTheme
中添加了这一行:它告诉android,您希望操作模式覆盖工具栏<item name="windowActionModeOverlay">true</item>
您必须使用以下导入才能使用AppCompatActivity
:
import androidx.appcompat.view.ActionMode;
// or
import android.support.v7.view.ActionMode;
actionMode = startSupportActionMode(callback);
并非如此:
actionMode = startActionMode(callback);
您的Activity会在工具栏上自动创建ActionMode,因为它已设置为supportActionToolbar。 样式将dsiplaying处理为叠加。
感谢@Kuffs和@Lefty。
答案 8 :(得分:0)
如果您看到视图树,则可以编写以下代码:
ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
traverseView(decorView);
/**
* traverse find actionmodebar
* @param root view
*/
public void traverseView(View root) {
if (root==null){
return;
}
if (root instanceof ActionBarContextView){
root.setVisibility(View.GONE);
return;
}
if ((root instanceof ViewGroup)) { // If view is ViewGroup, apply this method on it's child views
ViewGroup viewGroup = (ViewGroup) root;
for (int i = 0; i < viewGroup.getChildCount(); ++i) {
traverseView(viewGroup.getChildAt(i));
}
}
}
答案 9 :(得分:0)
你可以留下所有只在某些场景/手机/蓝月亮下有效的垃圾,然后简单地破解它(以非常干净的方式):
Groups
:<menu>
<group android:id="@+id/group_normal">
<item id="@+id/action_edit"/>
</group>
<group android:id="@+id/group_action_mode"
android:visible="false">
<item id="@+id/action_mode_1"/>
<item id="@+id/action_mode_2"/>
..
</group>
</menu>
Fragment
(或 Activity
)中:class MyFragment: Fragment() {
private var actionMode = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
toolbar.apply {
setNavigationOnClickListener {
if(actionMode) endActionMode(this)
else findNavController().navigateUp()
}
setOnMenuItemClickListener {
when(it.itemId) {
R.id.action_edit -> {
// start action mode
startActionMode(this)
}
R.id.action_mode_1 -> {
// todo
}
R.id.action_mode_2 -> {
// todo
endActionMode(this)
}
...
else -> return@setOnMenuItemClickListener false
}
true
}
}
}
private fun startActionMode(toolbar: Toolbar) {
with(toolbar.menu) {
setGroupVisible(R.id.group_normal, false)
setGroupVisible(R.id.group_action_mode, true)
}
toolbar.title = 0 // todo format number of selected items
actionMode = true
}
private fun endActionMode(toolbar: Toolbar) {
with(toolbar.menu) {
setGroupVisible(R.id.group_normal, true)
setGroupVisible(R.id.group_action_mode, false)
}
toolbar.setTitle(R.string.original_title)
actionMode = false
}
}
每次都按预期工作。根据需要添加额外功能。
PS:我不得不将代码片段包装在引用块中,否则代码样式似乎不起作用。如果有人可以修复它,请随时编辑。