使用“Powered By Chrome”和操作菜单打开自定义 WebView

2024-01-15

我最近注意到,当在一些 Android 应用程序中打开链接时,它们具有相似的外观和感觉,并且自定义操作菜单在自定义菜单下方带有“由 Chrome 提供支持”。这里面使用了什么组件还是仍然是 ChromiumWebView?希望我希望将它们添加到我的下一个项目中,其中涉及打开应用程序内的链接。

LinkedIn App LinkedIn App

Twitter App Twitter App

GMail App GMail App


It is Chrome 自定义标签 https://developer.chrome.com/multidevice/android/customtabs。您可以在 Google Chrome 中查看示例代码here https://github.com/GoogleChrome/custom-tabs-client.

尝试以下 util 类:

public class CustomTabs {

    private static final int TOOLBAR_SHARE_ITEM_ID = 1;

    public static void openTab(Context context, String url) {
        CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();

        enableUrlBarHiding(builder);
        setToolbarColor(context, builder);
        setSecondaryToolbarColor(context, builder);
        setCloseButtonIcon(context, builder);
        setShowTitle(builder);
        setAnimations(context, builder);
        setShareActionButton(context, builder, url);
        addToolbarShareItem(context, builder, url);
        addShareMenuItem(builder);
        addCopyMenuItem(context, builder);

        CustomTabsIntent customTabsIntent = builder.build();
        customTabsIntent.launchUrl(context, Uri.parse(url));
    }

    /* Enables the url bar to hide as the user scrolls down on the page */
    private static void enableUrlBarHiding(CustomTabsIntent.Builder builder) {
        builder.enableUrlBarHiding();
    }

    /* Sets the toolbar color */
    private static void setToolbarColor(Context context, CustomTabsIntent.Builder builder) {
        builder.setToolbarColor(ContextCompat.getColor(context, R.color.colorPrimary));
    }

    /* Sets the secondary toolbar color */
    private static void setSecondaryToolbarColor(Context context, CustomTabsIntent.Builder builder) {
        builder.setSecondaryToolbarColor(ContextCompat.getColor(context, R.color.colorPrimary));
    }    

    /* Sets the Close button icon for the custom tab */
    private static void setCloseButtonIcon(Context context, CustomTabsIntent.Builder builder) {
        builder.setCloseButtonIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_arrow_back));
    }

    /* Sets whether the title should be shown in the custom tab */
    private static void setShowTitle(CustomTabsIntent.Builder builder) {
        builder.setShowTitle(true);
    }

    /* Sets animations */
    private static void setAnimations(Context context, CustomTabsIntent.Builder builder) {
        builder.setStartAnimations(context, R.anim.slide_in_right, R.anim.slide_out_left);
        builder.setExitAnimations(context, R.anim.slide_in_left, R.anim.slide_out_right);
    }

    /* Sets share action button that is displayed in the Toolbar */
    private static void setShareActionButton(Context context, CustomTabsIntent.Builder builder, String url) {
        Bitmap icon = BitmapFactory.decodeResource(context.getResources(), android.R.drawable.ic_menu_share);
        String label = "Share via";

        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT, url);
        shareIntent.setType("text/plain");

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        builder.setActionButton(icon, label, pendingIntent);
    }

    /* Adds share item that is displayed in the secondary Toolbar */
    private static void addToolbarShareItem(Context context, CustomTabsIntent.Builder builder, String url) {
        Bitmap icon = BitmapFactory.decodeResource(context.getResources(), android.R.drawable.ic_menu_share);
        String label = "Share via";

        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT, url);
        shareIntent.setType("text/plain");

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        builder.addToolbarItem(TOOLBAR_SHARE_ITEM_ID, icon, label, pendingIntent);

    }

    /* Adds a default share item to the menu */
    private static void addShareMenuItem(CustomTabsIntent.Builder builder) {
        builder.addDefaultShareMenuItem();
    }

    /* Adds a copy item to the menu */
    private static void addCopyMenuItem(Context context, CustomTabsIntent.Builder builder) {
        String label = "Copy";
        Intent intent = new Intent(context, CopyBroadcastReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        builder.addMenuItem(label, pendingIntent);
    }

    public static class CopyBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String url = intent.getDataString();

            ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
            ClipData data = ClipData.newPlainText("Link", url);
            clipboardManager.setPrimaryClip(data);

            Toast.makeText(context, "Copied " + url, Toast.LENGTH_SHORT).show();
        }
    }
}

不要忘记将依赖项添加到您的app/build.gradle

dependencies {
    ...
    compile 'com.android.support:customtabs:25.2.0'
}

并注册您的BroadcastReceiver在你的AndroidManifest.xml

<application>
    ...
    <receiver android:name=".CustomTabs$CopyBroadcastReceiver" />
</application>

这是动画 xml:

Slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="100%p" android:toXDelta="0%p"
    android:duration="@android:integer/config_longAnimTime"
    android:interpolator="@android:anim/overshoot_interpolator" />

Slide_in_right.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-100%p" android:toXDelta="0%p"
    android:duration="@android:integer/config_longAnimTime"
    android:interpolator="@android:anim/overshoot_interpolator" />

Slide_out_left.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0" android:toXDelta="-100%p"
    android:duration="@android:integer/config_longAnimTime"
    android:interpolator="@android:anim/overshoot_interpolator" />

Slide_out_right.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0" android:toXDelta="100%p"
    android:duration="@android:integer/config_longAnimTime"
    android:interpolator="@android:anim/overshoot_interpolator" />
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用“Powered By Chrome”和操作菜单打开自定义 WebView 的相关文章

  • Android Studio 3.0 Canary 9 - 无法解析包

    我在 Android Studio 3 0 Canary 9 中遇到几个错误 这些错误是 无法解析 android 软件包 下面列出了一些错误 我刚刚安装了 SDK 的所有额外软件包 但仍然收到 gradle 构建错误 Error 82 1
  • android中向sqlite中插入大量数据

    目前 我必须一次向我的 Android 中插入超过 100 亿条数据 然而 内存不足的问题会使程序崩溃 sqlite 插入测试非常简单 只需使用 for 循环生成 sql 插入命令并通过 开始 和 提交 进行包装 private Array
  • 卸载后 Web 应用程序不显示“添加到主屏幕”

    这是我第一次创建网络应用程序 我设法解决了这个问题 所以我得到了实际的 chrome 提示 将其添加到主屏幕 然后我从手机上卸载了该网络应用程序 因为我想将其展示给我的同事 但是 屏幕上不再出现提示 问题 这是有意为之的行为还是我的应用程序
  • jQuery:离线后 POST 出错(iOS 和 Chrome)

    我构建了一个具有离线功能的 HTML5 Web 应用程序 使用 AppCache 程序流程为 Online 在网络上时 应用程序预加载一些基本信息 工作 Offline 用户拿着装有应用程序的平板电脑offline 然后在应用程序上执行他们
  • Android 30+ 中的视频捕获意图 - 只有所有者才能与待处理项目交互

    我正在尝试在我的应用程序上捕获视频 它可以在 android API 30 以下运行 但不能在 30 以上运行 似乎在 sdk 30 之后 android 不允许完全读取外部存储 作用域存储 我目前遇到这个错误 java lang Ille
  • 谷歌坐标认证

    当我尝试连接到 Google 坐标时 总是出现异常GoogleAuthException 我拥有 Google 地图协调中心许可证 我确实使用我的包应用程序名称和 SHA1 在 google 控制台中创建了我的客户端 ID 我将权限添加到清
  • 如何在android中获取Camera2 API的当前曝光

    In android hardware Camera旧的 我使用下面的代码获取当前曝光并获取它Camera Camera Parameters param mCamera getParameters currentExposure para
  • android xamarin 中的 reCaptcha

    我想在 Xamarin android 应用程序中实现验证码 我抓住了这个在 Android 中集成 googles reCaptcha 验证 https www c sharpcorner com article how to integ
  • 找不到处理意图 com.instagram.share.ADD_TO_STORY 的活动

    在我们的 React Native 应用程序中 我们试图让用户根据视图 组件中的选择直接将特定图像共享到提要或故事 当我们尝试直接使用 com instagram share ADD TO FEED 进行共享时 它以一致的方式完美运行 但是
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • Android Studio 0.4.3 Eclipse项目没有gradle

    在此版本之前 在 Android Studio 中按原样打开 Eclipse 项目似乎很容易 无需任何转换 我更喜欢 Android Studio 环境 但我正在开发一个使用 eclipse 作为主要 IDE 的项目 我不想只为这个项目下载
  • Android访问远程SQL数据库

    我可以直接从 Android 程序访问远程 SQL 数据库 在网络服务器上 吗 即简单地打开包含所有必需参数的连接 然后执行 SQL 查询 这是一个私人程序 不对公众开放 仅在指定的手机上可用 因此我不担心第三方获得数据库访问权限 如果是这
  • Android Studio - Windows 7 上的 Android SDK 问题

    我对 Google i o 2013 上发布的最新开发工具 Android Studio 有疑问 我已经成功安装了该程序并且能够正常启动 我可以导入现有项目并对其进行编辑 但是 当我尝试单击 SDK 管理器图标或 AVD 管理器图标时 或者
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 将两个文本视图并排放置在布局中

    我有两个文本视图 需要在布局中并排放置 并且必须遵守两条规则 Textview2 始终需要完整显示 如果布局中没有足够的空间 则必须裁剪 Textview1 例子 文本视图1 文本视图2 Teeeeeeeeeeeeeeeeeextview1
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两
  • 强制 Listview 不重复使用视图(复选框)

    我做了一个定制Listview 没有覆盖getView 方法 Listview 中的每个项目都具有以下布局 联系布局 xml

随机推荐

  • 如何在 mongodb 中按周对文档进行分组

    id ObjectId 568b650543712795bf864a45 companyId 55e2d7cfdc8f74d14f5c900f timeStamp ISODate 2014 12 03T18 30 00 000Z id Ob
  • NLog 无法与 MSTest 一起使用,配置应该放在哪里?

    我们最近将测试从 NUnit 迁移到 MSTest 我正在努力让之前通过的测试运行 据我所知 MSTest 无法检测到 NLog 配置 我的 App config 中有 Nlog 配置 这不会导致 NUnit 出现问题 有人有什么想法吗 改
  • Gettext自动评论生成

    我正在使用 gettext 为 php 项目执行 i18n 操作 我想使用自动评论功能 http www gnu org software gettext manual gettext html PO Files在翻译用 id 替换的长短语
  • int* x[n][m] 和 int (*x) [n][m] 有什么区别?

    照我看来int x n m 宣称x是一个指向整数的指针的二维数组 因此分配内存应该像x i j new int正如预期的那样 它工作得很好 现在 如果我将声明更改为 int x n m x i j new int不再有效并导致编译错误 x
  • iOS SpriteKit SKAction 完成调用不起作用/创建奇怪的结果

    我试图让 SKNode 根据命令移动到屏幕上 我设置了以下 SKAction 链 以便 1 节点向上移动并移出屏幕 然后 2 节点向下移动到起始位置 然后 3 开始四处移动 我使用以下代码来尝试实现这一点 SKAction moveUp S
  • Malloc 分配方案

    是的 我正在学习计算机系统课程 我对实现 malloc 的各种分配方案有一些疑问 对于显式列表 如果我使用类似 LIFO 的堆栈实现 malloc 那么拥有指向先前释放的内存的指针的确切目的是什么 比如为什么需要双向链表 单链表不是也能工作
  • 如何使用 jasmine 自定义记者制作失败规格列表并发布到 Slack?

    我正在尝试使用自定义 jasmine 报告器并获取 specDone 函数中所有失败规格的列表 specDone function result if result status failed failedExpectations push
  • 如何在 ggplot 中为地图中的多个图层自定义图例?

    我正在尝试修复我的标题 但在创建它时遇到问题 我想要类 填充 形状限制 颜色 点 颜色 和网格 填充 NA 的标题 我把它们全部放进去aes 但我没有得到预期的结果 有谁能够帮助我 谢谢 library geobr library sf l
  • 旋转 y 轴标签

    我正在尝试旋转 Y 轴的标题 使其处于水平位置 我不希望刻度标签只是 Y 轴标题的水平方向 我必须使用子图 因为我要同时制作多个图 这是下面的脚本 我在其中尝试旋转 Y 轴标题 import matplotlib pyplot as plt
  • Xstream jodatime 本地日期显示

    我正在使用 xstrem 将 jodatime 本地日期序列化为 xml 然而 当输出生成的 xml 时 LocalDate 的格式并不易于阅读 见下文
  • 在 javac 中禁用 StringBuilder 优化

    在 Java 中使用普通字符串连接时 javac 会在可以使用的地方对其进行优化StringBuilder相反 或 Java 5 之前的 StringBuffer 就我而言 关闭所有这些 然后使用 bog 标准 append 方法进行字符串
  • 如何自动调整tinyMCE的大小?

    我有一个设置在 TextArea 上的 TinyMCE 并且我希望该编辑器区域始终占据其父 div 的所有空间 我有一个 JS 函数 可以获取当前空间并将 textarea style height 设置为它 但是当我启用 TinyMCE
  • 在 Android 应用程序中更改 HttpClient 的 OpenSSL 库

    我需要使用自定义 OpenSSL 库Http客户端在我的项目中 我已经编译了libcrypto so and libssl so对于 Android 并将文件放在 jniLibs 文件夹中 应用程序 Heartbleed Scanner 可
  • NodeJS 无限循环内存消耗

    我不知道这是否是 Node 或 V8 的错误 但如果我运行以下代码 节点进程会泄漏内存 GC 似乎从未启动 并且在几秒钟内它就消耗了 gt 1GB 的内存 这是意想不到的行为 我错过了什么吗 这是代码 for console log 1 1
  • WPF 中的身份验证和角色

    我正在WPF中做一个项目 我需要对用户进行身份验证并根据角色提供模块的可访问性 我有更好的方法在 WPF 中实现这一目标吗 这部分取决于您需要代码的安全程度 不过 对于所有用例 请使用模型 视图 视图模型模式 在每个 ViewModel 中
  • ContextWrapper 中的 NullPointer 异常

    我有一个名为 FileGeneration 的类 它扩展了 Activity在 FileGeneration 中我有一个名为 protected OutputStream openAndWriteFile Set the Context m
  • Internet Explorer 9 拖放 (DnD)

    有谁知道为什么以下网站拖放示例 以及许多其他在线教程 在 Internet Explorer 9 中不起作用 Chrome FireFox 和 Safari 都可以 http www html5rocks com tutorials dnd
  • Java 密钥库未通过 PKCS12 完整性检查,但 keytool 可以工作

    我有一些 PCKS12 证书 由两个环境以不同的方式提供服务 当我们上传到DEV环境时 java就可以解析它了 但它在产品上失败了 服务器是 Microsoft DotNet 解决方案 负责证书操作 生成的密钥库的密码为空 当我在 Wind
  • 如何修复 iframe 页面重新加载时的 chrome 闪烁

    在 iframe 中重新加载内容时 Chrome 会闪烁 是否可以通过任何方式避免这种情况 考虑 用 js 包装 a links 会产生一些神奇的效果 content html 中的元标记 我对 iframe 中的 html 有源代码控制
  • 使用“Powered By Chrome”和操作菜单打开自定义 WebView

    我最近注意到 当在一些 Android 应用程序中打开链接时 它们具有相似的外观和感觉 并且自定义操作菜单在自定义菜单下方带有 由 Chrome 提供支持 这里面使用了什么组件还是仍然是 ChromiumWebView 希望我希望将它们添加