在 StackOverflow 上寻找类似问题的答案,我发现人们通常建议 2 种方法:
- 将可绘制对象加载到内存中并将ConstantState 或位图本身与另一个进行比较。
- 在视图中设置一个带有可绘制 id 的标签,并在需要时比较标签
那个。
就个人而言,出于性能原因,我喜欢第二种方法,但是使用适当的标签标记一堆视图既痛苦又耗时。这在一个大项目中可能非常令人沮丧。就我而言,我需要编写很多 Espresso 测试,这些测试需要比较 TextView drawables、ImageView 资源、View 背景和前景。很多工作。
所以我最终想出了一个解决方案,将“肮脏”的工作委托给自定义充气机。在每个膨胀的视图中,我都会搜索特定的属性,并为视图设置一个标签,如果找到的话,它会带有资源 id。这种方法与来自Calligraphy 的人几乎相同。我为此写了一个简单的库:TagView
如果你使用它,你可以检索任何预定义的标签,包含在 xml 布局文件中设置的可绘制资源 id:
TagViewUtils.getTag(view, ViewTag.IMAGEVIEW_SRC.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_LEFT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_TOP.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_RIGHT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_BOTTOM.id)
TagViewUtils.getTag(view, ViewTag.VIEW_BACKGROUND.id)
TagViewUtils.getTag(view, ViewTag.VIEW_FOREGROUND.id)
该库实际上支持任何属性。您可以手动添加它们,只需查看 Github 上的 Custom attributes 部分。
如果您在运行时设置可绘制对象,您可以使用方便的库方法:
setImageViewResource(ImageView view, int id)
在这种情况下,标记是在内部为您完成的。如果你使用 Kotlin,你可以编写一个方便的扩展来调用 view 本身。像这样的:
fun ImageView.setImageResourceWithTag(@DrawableRes int id) {
TagViewUtils.setImageViewResource(this, id)
}
您可以在Tagging in runtime找到更多信息