从android框架覆盖布局xml

Posted

技术标签:

【中文标题】从android框架覆盖布局xml【英文标题】:Override layout xml from android framework 【发布时间】:2017-11-19 05:48:00 【问题描述】:

问题

我想覆盖 android 命名空间中的布局文件,例如R.layout.popup_menu_item_layout(即referenced from code 和com.android.internal.R.layout.popup_menu_item_layout)。通过说 override,我假设在项目中声明一个 xml 文件,该文件将优先于框架拥有的布局。

注意,这只是一个示例布局,因此问题涉及sdk/platforms/android-XX/data/res/layout 目录中存在的每个布局。

我尝试过的

工具:覆盖

有一个undocumented tools:override 标记可用,它会覆盖特定资源。有关示例,请参阅 this 答案,它会覆盖来自 Design Support Library 的值,not 来自 Android 框架。

对布局的根标签应用tools:override="true"不会生效。


XML 布局参考 - refs.xml

如this 帖子中所述,在/values/ 目录中声明一个refs.xml 文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item type="layout" name="activity_main">@layout/activity_second</item>
</resources>

一旦使用activity_main.xml,将引用activity_second.xml。有an answer 建议使用这种技术来替换Snackbar 的布局。

这也不会生效。

问题

是否有任何合法的方法可以覆盖/替换 android 包中的布局文件?

【问题讨论】:

如果您是膨胀布局的人,只需修改您的代码以使用替换。如果您试图替换其他正在膨胀的布局(例如,PopupMenu),那么 AFAIK 是不可能的。您可以尝试分叉该类并创建自己的版本,然后使用您的替换布局。 通常这些 API 隐藏在公共 API 之后(PopupMenu 使用 SomeClassA,它使用 SomeClassB,这会扩大这种布局),这意味着我必须坚持多层次反思,希望能找到足够多的接缝,达到想要的效果。不过感谢您的回复。 你最终也会分叉这些。最终,你要么得到一整套类,要么遇到不可分叉的东西(例如,android.view.View,使用native 方法的东西)。在后一种情况下,您继续前进并以其他方式解决您的整体问题。因此,例如,我以这种方式分叉了the entirety of Android 7.0's network security configuration,丢弃了不能在旧设备上使用的位,作为创建反向移植的一部分。 您是否尝试过简单地将布局文件复制到您的代码库中?名称必须保持不变,如果你有多个布局大小来复制它们,你也需要小心。您还必须解决沿途出现的所有尺寸错误。我记得当我需要从 google cast 支持库(媒体控制器)修改活动中的布局时,这对我有用,这样我就能够摆脱 2 窗格布局并更改颜色、品牌......一切。 你有没有尝试在你的项目中添加一个包名为“com.android.internal”的模块库,这将生成你自己的com.android.internal.R,尽管编译如何解决依赖冲突,也许您可​​以覆盖布局链接? 【参考方案1】:

我知道这是一个老问题,但我也想用自己的方式覆盖库布局,这就是我的做法。

有问题的布局称为design_bottom_navigation_item

在 refs.xml 我添加了以下内容:

<resources xmlns:tools="http://schemas.android.com/tools">
    <item name="design_bottom_navigation_item" type="layout" tools:override="true">@layout/bottom_navigation_item</item>
</resources>

我将解释这四个部分。

名称:这是您要覆盖的布局的名称 类型:您尝试覆盖的资源类型,在本例中为布局。 tools:override:这是您告诉 Android Studio 用您自己的布局覆盖库布局的方式。 :您可以在此处指定要使用的资源。

您可以通过这种方式对任何资源类型执行此操作。

【讨论】:

您所指的布局不是来自框架,它来自一个库,您将附加到您的项目(准确地说是设计支持库)。不幸的是,您的回答对我没有帮助,因为通过您提到的方法,您无法覆盖例如R.layout.popup_menu_item_layout。问题本身已经指出了您的解决方案。谢谢。 非常适合替换第三方库中的错误 xml 布局!【参考方案2】:

你想做什么?

如果只想替换菜单项的外观,您可以尝试以下方法:

    创建自定义MyMenuAdapter extends MenuAdapter 重写 getView 方法以从适配器返回视图。

【讨论】:

查看有问题的:Note, this is just an example layout, so the question concerns to each layout that's present in sdk/platforms/android-XX/data/res/layout directory. 不幸的是,您的答案还没有接近。 哦...每个文件。我错过了。因此,基本上,您正在寻找替换使用的内部布局文件。这称为自定义固件,如果不重新编译操作系统就无法完成。如果您只是为您的应用程序寻找它 - 您必须替换所有文件,重新编译并在您的应用程序中使用新代码,并且不要忘记使用不同的包名称,例如:com.myapp.repackaged.com.layout.internal 随便什么【参考方案3】:

您正在尝试在运行时在应用程序本身上自定义您的 sdk。

这不是它的工作原理。

如果您在您的项目(任何技术)上使用 SDK,并且您需要修改一些行为,您将调整此 SDK,然后使用此新闻定制版本编译您的项目。 尝试在运行时修改它不是一个好主意。 您将面临多个问题(复古兼容性、安全触发、TREBLE 不兼容、依赖问题等)

你有 4 种可能做你想做的事:

    制作您自己的 android rom,您将在其中应用您的修改 将你需要修改的资源复制到一个带有标签的假xmlObject上,在你的应用程序的onPostCreate之后,你就可以修改when通胀了。您可以概括此行为,它将模拟 sdk 覆盖。 Make your own sdk :) 多级反射,但是,稳定版本不可能成功

当然,这些解决方案都不适用于公共应用。

【讨论】:

【参考方案4】:

不知道您的问题是否已解决,但简单的解决方案是创建与框架布局名称相同的新布局(在本例中为 popup_menu_item_layout)。然后去android google源码复制xml内容popup_menu_item_layout

所以你可以自定义任何你想要的东西。但请记住不要更改任何视图的 id。

【讨论】:

以上是关于从android框架覆盖布局xml的主要内容,如果未能解决你的问题,请参考以下文章

Android软键盘弹出,覆盖h5页面输入框问题

Android软键盘弹出,覆盖h5页面输入框问题

相对布局relativeLayout

如何从 XML Android 开发中选择要显示的内容 [重复]

xml Android 布局的问题。布局与工具栏重叠

框架布局