从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的主要内容,如果未能解决你的问题,请参考以下文章