Android xml 没有子类化的全局自定义标签

Android xml global custom tag without subclassing

我知道如何创建自定义样式属性定义并在自定义视图中获取值(来自此 link):

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0);
String str = a.getString(R.styleable.MyCustomView_my_custom_attribute);

但我想知道是否可以定义一个 "global" 标签,我可以将其应用于任何视图,无论是自定义视图还是来自 Android SDK。

假设我想对包含该属性的视图执行一个静态方法,但要避免对视图的任何引用(如 FindViewById):

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    whatever:custom_global_tag="key" />

MyStaticClass.Process(View view, String key) {}

这可能吗?

编辑

澄清一下,我真正需要的是一个字符串。目标是将一个字符串转换为另一个字符串并将新值分配给文本 属性.

我的环境是 Xamarin,但任何本机方法都可以转换为 Xamarin,因此欢迎所有建议

尝试Theme?

A theme is a style applied to an entire Activity or application, rather than an individual View (as in the example above). When a style is applied as a theme, every View in the Activity or application will apply each style property that it supports.

注意:仅适用于 属性 视图支持。

编辑 #1

如果您想在每个视图上传递不同的字符串,只需使用 android:tag

类似于:

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:tag="key" />

并获取字符串

String key = textView.getTag();

编辑#2

设置一个标签来标识您想要的视图。

在activity中,遍历所有视图以找到像

这样标识的视图
final ViewGroup viewGroup = (ViewGroup)((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);
for(int i = 0; i < viewGroup.getChildCount(); i++) {
    View childView = viewGroup.getChildAt(i);
    if ("identificaton".equals(childView.getTag())) {
        // do some work to child view.
    }
}

viewGroup部分可以勾选the post

我自己没试过,不过理论上是可以的。有关示例,请参见 Calligraphy library

您可以直接在值资源文件中声明全局属性(就像它们在框架中所做的那样):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="myCustomAttr" format="string"/>
</resources>

然后你可以将它添加到任何视图而无需任何前缀(但是你会遇到 Lint 错误):

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    myCustomAttr="key"
    tools:ignore="MissingPrefix" />

最后,您应该能够从您的视图 AttributeSet 中检索它(在视图构造函数中给出)。

String myCustomValue = attrs.getAttributeValue(R.attr.myCustomAttr);

如果您不创建自定义视图,则会出现问题:据我所知,创建视图后您无权访问 AttributeSet。你将不得不在布局过程中将自己挂在某个地方 inflation...

您可以使用数据绑定库 a @BindingAdapter method 完成此操作。

根据您的帮助 (@assistne),我最终得到了一种递归方法,该方法将扫描整个视图树以查找带有以 "translate:" 开头的标签的视图。到目前为止,它就像一个魅力:

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:tag="translate:TextWithLineBreakCharacters" />
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:tag="translate:Animals"/>

助手 class (Xamarin/C#):

public static class I18NAndroidHelper
{
    public static void Translate(object view)
    {
        if(view is TextView)
        {
            var textView = (TextView)view;
            var tag = (string)textView.Tag;
            if(tag != null && tag.StartsWith("translate:", StringComparison.Ordinal))
            {
                var key = tag.Split(new [] {":"}, StringSplitOptions.None)[1];
                textView.Text = key.Translate(); // Translate() is an string extension method
            }
        }
        else if(view is ViewGroup)
        {
            var viewGroup = (ViewGroup)view;
            var childCount = viewGroup.ChildCount;
            for(var i = 0; i < childCount; i++)
                Translate(viewGroup.GetChildAt(i));
        }
        else if(view is Activity)
        {
            var activity = (Activity)view;
            var content = activity.FindViewById<ViewGroup>(Android.Resource.Id.Content);
            Translate(content);
        }
    }
}

在 Activity OnCreate:

I18NAndroidHelper.Translate(this);