菜单项#getTag()

时间:2011-05-11 17:06:52

标签: android

View的子类上有一个getTag()方法,它从.xml返回android:tag属性的值。 我希望MenuItem也一样......是否可以将其转换为View? 因为item元素还允许.xml ...

中的标记属性

更新:我的目标是在.xml中设置一个标记,即"notranslate",并在运行时查询它(我们在运行时手动本地化,不要问.. 。)

3 个答案:

答案 0 :(得分:2)

总是可以强制转换,但是,在编译时不能检查任何Interface,只能运行时。这通常是许多人不建议投射您无法控制的界面的原因。拥有正确的错误检查代码是确保此类转换不会破坏您的代码的最佳方法。

对于投射,MenuItemInterface还是View并不重要,但它引用的对象必须是View'之一s子类,如果不是View本身。如果您要转换它,try转换和catch一个ClassCastException以防万一,因为这是将在运行时抛出的错误。

另一种选择是,由于MenuItem只是一个界面,您可以轻松创建一个View子类,利用MenuItem允许您进行强制转换。如果您正在执行许多发射器的自定义ContextMenu,那么您的答案几乎可以完成。

希望这有帮助, FuzzicalLogic

答案 1 :(得分:1)

MenuItem是一个界面。任何类都可以实现此接口,因此将始终安全地将MenuItem强制转换为View。您可以使用“instanceOf”运算符来测试以查看实现MenuItem接口的对象是否确实是View。

我知道你想在菜单的XML定义中定义一个标志,然后在运行时询问该标志以做出程序化的决定。

Menu Resource Documentation记录可以在XML中设置的属性。你可以考虑使用(滥用)其中一个设置,如“android:alphabeticShortcut”来编码标志,并使用MenuItem :: getAlphabeticShortcut()方法来获取值。这不需要强制转换 - 它只是为了您自己的目的使用MenuItem XML构造/类中的现有字段。

执行此操作的方法可能不那么简单,就是将一个简单的表保存在单独的资源文件中,该文件列出了菜单项标识符以及与该标识符相关联的特殊行为,例如翻译或不翻译。

或者创建一个简单的类,该类具有使用逻辑“@ [+] [package:] id / resource_name”资源标识符作为表的键的硬编码的配置信息的表。虽然这并不能将它全部保存在一个地方(在XML中),但它的处理方式不是在未使用的属性中编码信息,或者依赖于不改变的ID。 “table”可以实现为带有嵌入式switch语句的静态方法,允许代码如“if(TranslationTable.shouldTranslate(menuItem.getItemId())){do translation}”

答案 2 :(得分:0)

我遇到了类似的问题,因为我想将一些任意数据与每个菜单项相关联,这样我就可以通用方式处理菜单项,而无需对代码中的单个项ID进行硬编码检查。

我所做的是针对特定的菜单项(例如@ + id / foo)有一个TypedArray使用与菜单项ID相同的名称定义。您也可以使用其他类型的资源执行此操作。

所以要做关联,你得到资源条目名称(在我的例子中为foo)然后用它来查找不同类型的其他资源的id(在我的例子中是@ array / foo)。

在我的菜单处理程序中,我有这样的代码:

Resources resources = getResources();
String name = resources.getResourceEntryName(item.getItemId());
int id = resources.getIdentifier(name, "array", "com.example");

if(id != 0)
{
    TypedArray data = resources.obtainTypedArray(id);

    // Use the typed array to get associated data
}

修改

实际上它比那更容易。除了您不希望具有相同ID的多个菜单项之外,菜单项上的ID没有什么特别之处。 id不必是@ + id / foo的形式。它实际上也可以引用其他资源。所以在我上面的例子中,不是让菜单有一个@ + id / foo的id,而是使用资源管理器来查找@ array / foo,我改为实际上让菜单项的id为@ array / FOO。

现在我的onOptionsItemSelected我有这个:

Resources resources = getResources();

if("array".equals(resources.getResourceTypeName(item.getItemId())))
{
    TypedArray data = resources.obtainTypedArray(item.getItemId());

    // Use the typed array
}