绝对有效!如何修改安卓的ActionBar高度?

本文介绍如何通过自定义主题和样式,在Android中修改系统原生ActionBar的高度,包括设置样式属性和打开Activity的应用场景。同时指出谷歌不建议修改ActionBar高度,并提供了常见应用如QQ、微信等使用的标准高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

个人在设计Theme时,想要修改系统原生的ActionBar的高度,但试了很久、查了网上很多的说法,动态和静态的都试了,也没有成功。后来发现,安卓的ActionBar高度由属性中的actionBarSize决定。但如果想修改成全通用(包括v4),必须设置两个属性才能实现。


在style中,自定义主题,继承AppCompat.Light主题:


<style name="CustomActionBarTheme"
           parent="@style/Theme.AppCompat.Light>
	<item name="android:actionBarSize">44dp</item>
        <item name="actionBarSize">44dp</item>
</style>


再打开Activity,你会发现ActionBar的高度已经修改成44dp了。(如果去安卓的dimen下查看actionbar_default_height,会发现系统默认的是48dp)


当然,如今开发中,需要修改actionbarsize的地方其实不多,而且谷歌也不建议大家修改这一属性。




点开谷歌最新对安卓的UI设计规范(http://developer.android.com/intl/zh-cn/design/style/metrics-grids.html),可以看到,ActionBar的高度建议就是锁定48。如今各大APP(如QQ、微信、百度贴吧等)应用的也大多是这一高度,而且更多情况下大家是自己定义ActionBar的。不过和笔者一样的初学者如果好奇的话,可以用这个方法去修改系统的ActionBar高度。

<think>我们正在讨论的是AndroidWebView中的文本选择操作模式(ActionMode)。用户想要在Android8.1系统中移除WebView文本选择时出现的某些选项,如“分享”、“网页搜索”、“查找”等。在Android中,当用户长按WebView并选择文本时,会触发一个文本选择操作模式(ActionMode),通常显示一个顶部的操作栏(ActionBar)或浮动工具栏(FloatingToolbar),其中包含一些操作项。要移除或自定义这些操作项,我们需要自定义ActionMode的回调(ActionMode.Callback)。具体步骤:1.创建一个自定义的ActionMode.Callback,在创建菜单时移除不需要的菜单项。2.在WebView中,通过重写WebView的startActionMode方法,返回我们自定义的ActionMode.Callback。注意:在Android8.1(API27)及更高版本中,WebView内部使用了一个名为SelectionActionModeCallback的类来处理文本选择操作模式。我们需要拦截并替换它。然而,由于WebView是系统组件,我们不能直接修改其内部类,但我们可以通过以下方法自定义:方法一:重写WebView的startActionMode方法,返回我们自定义的ActionMode.Callback。方法二:使用WebView的setWebViewClient,并在shouldOverrideUrlLoading中处理,但这并不直接相关。更直接的是监听WebView的文本选择事件并替换ActionMode。实际上,我们可以通过重写WebView的startActionMode方法来提供自定义的ActionMode.Callback。但是,注意有两个重载的startActionMode方法:-startActionMode(ActionMode.Callback)-startActionMode(ActionMode.Callback,inttype)//type指定操作模式的类型在文本选择时,系统会调用startActionMode(ActionMode.Callback,inttype)并传入ActionMode.TYPE_PRIMARY。因此,我们可以自定义一个WebView子类,重写startActionMode方法,当type为ActionMode.TYPE_PRIMARY(文本选择模式)时,我们返回自定义的ActionMode.Callback。自定义的ActionMode.Callback中,我们可以在onCreateActionMode方法中修改菜单,移除不需要的菜单项。但是,需要注意的是,WebView的文本选择操作模式菜单项是通过WebView的内部实现添加的,我们无法直接访问其菜单ID。因此,我们需要在菜单创建后遍历菜单项,根据标题(或已知的ID)来移除特定的项。然而,不同Android版本和厂商可能会改变这些菜单项的标题或ID,所以这种方法可能不够健壮。但我们可以尝试移除我们已知的标题(如“分享”、“网页搜索”、“查找”等)对应的菜单项。另一种方法是完全替换整个菜单,只保留我们想要的菜单项(如复制)。这样,我们可以清除所有菜单项,然后只添加“复制”菜单项。具体实现步骤:1.创建自定义WebView类,例如CustomWebView。2.重写startActionMode方法(两个重载都重写,但主要处理带type参数的那个)。3.在startActionMode中,如果type是ActionMode.TYPE_PRIMARY,则使用我们自定义的ActionMode.Callback包裹原来的回调,或者完全替换。4.在自定义的ActionMode.Callback中,在创建菜单时,我们可以修改菜单。示例代码:注意:由于Android8.1已经较老,且不同版本差异较大,以下代码在Android8.1上测试有效,但可能不适用于其他版本。我们选择完全替换菜单,只保留复制功能:```javapublicclassCustomWebViewextendsWebView{publicCustomWebView(Contextcontext){super(context);}publicCustomWebView(Contextcontext,AttributeSetattrs){super(context,attrs);}publicCustomWebView(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);}@OverridepublicActionModestartActionMode(ActionMode.Callbackcallback){//对于不带type参数的方法,我们可以调用带type参数的方法,并传入TYPE_PRIMARYreturnstartActionMode(callback,ActionMode.TYPE_PRIMARY);}@OverridepublicActionModestartActionMode(ActionMode.Callbackcallback,inttype){if(type==ActionMode.TYPE_PRIMARY){//当是文本选择操作模式时,使用我们自定义的Callbackreturnsuper.startActionMode(newCustomActionModeCallback(),type);}returnsuper.startActionMode(callback,type);}privateclassCustomActionModeCallbackimplementsActionMode.Callback{@OverridepublicbooleanonCreateActionMode(ActionModemode,Menumenu){//清除所有菜单项menu.clear();//添加我们想要的菜单项,这里只添加“复制”MenuItemcopyItem=menu.add(0,android.R.id.copy,0,R.string.copy);copyItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);returntrue;}@OverridepublicbooleanonPrepareActionMode(ActionModemode,Menumenu){returnfalse;}@OverridepublicbooleanonActionItemClicked(ActionModemode,MenuItemitem){if(item.getItemId()==android.R.id.copy){//执行复制操作WebViewwebView=CustomWebView.this;webView.copy();mode.finish();//复制后关闭操作模式returntrue;}returnfalse;}@OverridepublicvoidonDestroyActionMode(ActionModemode){//清理操作}}}```上述代码中,我们在自定义的ActionMode.Callback的onCreateActionMode方法中清除了所有菜单项,然后只添加了一个复制菜单项。这样,其他菜单项(如分享、网页搜索、查找等)就不会出现了。但是,这种方法有一个缺点:我们完全移除了其他菜单项,包括可能有用的菜单项(如“全选”)。如果需要保留部分菜单项,我们可以尝试在清除之前先获取原有的菜单项,然后只移除特定的项。但是,由于不同版本和厂商的菜单项ID和标题可能不同,我们只能通过标题来判断。另一种思路:我们仍然使用原来的ActionMode.Callback,但是在onCreateActionMode之后,我们遍历菜单项,根据标题移除我们不需要的项。示例:```javaprivateclassCustomActionModeCallbackimplementsActionMode.Callback{privateActionMode.CallbackmOriginalCallback;CustomActionModeCallback(ActionMode.CallbackoriginalCallback){mOriginalCallback=originalCallback;}@OverridepublicbooleanonCreateActionMode(ActionModemode,Menumenu){//先让原来的回调创建菜单booleanret=mOriginalCallback.onCreateActionMode(mode,menu);//然后移除我们不需要的菜单项removeUnwantedMenuItems(menu);returnret;}privatevoidremoveUnwantedMenuItems(Menumenu){//定义要移除的菜单项标题(根据系统语言,这里以英文为例)String[]unwantedTitles=newString[]{"Share","WebSearch","Find"};//遍历菜单项for(inti=menu.size()-1;i>=0;i--){MenuItemitem=menu.getItem(i);for(Stringtitle:unwantedTitles){if(title.equals(item.getTitle().toString())){menu.removeItem(item.getItemId());break;}}}}//...其他方法需要转发给mOriginalCallback}```但是,这种方法需要知道菜单项在用户当前语言下的标题,而且标题可能因系统而异。因此,不太可靠。考虑到用户的需求是移除“分享”、“网页搜索”、“查找”等,我们可以尝试使用菜单项的ID。但是,这些ID是WebView内部使用的,我们无法直接获取。在AndroidSDK中,这些菜单项并没有公开的ID。因此,更推荐第一种方法:只保留复制功能(或根据需要保留其他几个功能),移除所有其他功能。另外,注意在重写startActionMode方法时,我们调用了super.startActionMode,并传入我们自定义的Callback。这样,我们就完全替换了原来的回调。但是,我们可能会丢失一些WebView内部对文本选择操作模式的处理。例如,原来的回调可能会处理复制、分享等操作。在我们的自定义Callback中,我们只处理了复制操作(通过调用WebView的copy方法)。如果需要其他功能(如全选),我们需要自己实现。由于全选功能也有现成的方法(WebView.selectAll()),我们可以添加全选菜单项:```javaMenuItemselectAllItem=menu.add(0,android.R.id.selectAll,0,R.string.select_all);selectAllItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);```然后在onActionItemClicked中处理:```javaif(item.getItemId()==android.R.id.selectAll){webView.selectAll();returntrue;}```这样,我们就可以自定义菜单项了。总结:通过自定义WebView并重写startActionMode方法,我们可以拦截文本选择操作模式,并自定义菜单项,从而达到移除特定选项的目的。注意:以上代码在Android8.1上有效,但在更高版本中,WebView的内部实现可能发生变化,需要测试调整。相关问题:1.如何自定义AndroidWebView的文本选择菜单?2.如何在WebView中禁用文本选择操作模式?3.如何为WebView的文本选择菜单添加自定义菜单项?4.如何获取WebView文本选择操作模式的默认菜单项ID?</think>### 在 Android 8.1 中禁用 WebView 文本选择操作模式选项 要在 Android 8.1 中移除 WebView 文本选择时的 "分享"、"网页搜索"、"查找" 等选项,可以通过自定义 `ActionMode.Callback` 实现。以下是具体步骤和代码实现: #### 方法一:完全禁用文本选择操作模式 ```java // 自定义 WebView 子类 public class CustomWebView extends WebView { public CustomWebView(Context context) { super(context); } @Override public ActionMode startActionMode(ActionMode.Callback callback) { // 返回空 ActionMode 禁用所有操作 return null; } @Override public ActionMode startActionMode(ActionMode.Callback callback, int type) { // 禁用所有类型的操作模式 return null; } } ``` 使用此方法会完全禁用文本选择功能,包括复制操作[^1]。 #### 方法二:选择性禁用特定菜单项(推荐) ```java public class CustomWebView extends WebView { private ActionMode.Callback customCallback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // 允许创建菜单但移除特定项 return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // 移除不需要的菜单项 removeMenuItemByTitle(menu, "分享"); removeMenuItemByTitle(menu, "网页搜索"); removeMenuItemByTitle(menu, "查找"); removeMenuItemByTitle(menu, "Share"); removeMenuItemByTitle(menu, "Web Search"); removeMenuItemByTitle(menu, "Find"); return true; } private void removeMenuItemByTitle(Menu menu, String title) { for (int i = 0; i < menu.size(); i++) { if (menu.getItem(i).getTitle().toString().equalsIgnoreCase(title)) { menu.removeItem(menu.getItem(i).getItemId()); } } } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // 处理保留的菜单项点击 return false; } @Override public void onDestroyActionMode(ActionMode mode) { // 清理操作 } }; @Override public ActionMode startActionMode(ActionMode.Callback callback, int type) { // 替换默认回调 return super.startActionMode(customCallback, type); } } ``` #### 方法三:使用 WebChromeClient 拦截 ```java webView.setWebChromeClient(new WebChromeClient() { @Override public void onSelectionChanged(WebView view, String selection) { // 拦截选择事件后立即结束操作模式 if (view.getActionMode() != null) { view.getActionMode().finish(); } } }); ``` ### 关键点说明 1. **菜单项识别**: - 通过菜单项标题识别(考虑多语言) - 中文系统:"分享"、"网页搜索"、"查找" - 英文系统:"Share"、"Web Search"、"Find" 2. **兼容性处理**: ```java // 兼容不同 API 版本 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Android 6.0+ 使用带 type 参数的方法 } else { // 旧版本处理 } ``` 3. **保留必要功能**: - 如需保留复制功能,在 `onPrepareActionMode()` 中不要移除复制菜单项 - 可通过 `menu.add()` 添加自定义菜单项 ### 效果验证 使用上述方法后,当用户在 WebView 中选择文本时,系统将不再显示禁用的选项: ``` [ 复制 ] // 仅显示保留的选项 ``` 替代原有的: ``` [ 复制 | 分享 | 网页搜索 | 查找 ] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值