我想从我的strings.xml文件中的另一个字符串引用一个字符串,如下所示(特别注意“message_text”字符串内容的结尾):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="button_text">Add item</string>
    <string name="message_text">You don't have any items yet! Add one by pressing the \'@string/button_text\' button.</string>
</resources>

我已经尝试了上面的语法,但然后文本打印出“@string/button_text”作为明文。不是我想要的。我希望消息文本打印“您还没有任何项目!”按‘添加项目’按钮添加一个。”

有什么已知的方法可以达到我想要的吗?

理由是: 我的应用程序有一个项目列表,但当该列表为空时,我显示一个“@android:id/空”TextView代替。TextView中的文本通知用户如何添加新项。我想让我的布局万无一失的变化(是的,我是傻瓜的问题:-)


当前回答

我知道这是一个老帖子,但我想分享我为我的一个项目想出的快速而肮脏的解决方案。它只适用于textview,但可以 也可以适应其他小部件。注意,它要求链接用方括号括起来(例如[@string/foo])。

public class RefResolvingTextView extends TextView
{
    // ...

    @Override
    public void setText(CharSequence text, BufferType type)
    {
        final StringBuilder sb = new StringBuilder(text);
        final String defPackage = getContext().getApplicationContext().
                getPackageName();

        int beg;

        while((beg = sb.indexOf("[@string/")) != -1)
        {
            int end = sb.indexOf("]", beg);
            String name = sb.substring(beg + 2, end);
            int resId = getResources().getIdentifier(name, null, defPackage);
            if(resId == 0)
            {
                throw new IllegalArgumentException(
                        "Failed to resolve link to @" + name);
            }

            sb.replace(beg, end + 1, getContext().getString(resId));
        }

        super.setText(sb, type);
    }
}

这种方法的缺点是setText()将CharSequence转换为 String,这是一个问题,如果你传递像SpannableString;为我的 项目这不是一个问题,因为我只使用它的textview,我不需要 访问我的活动。

其他回答

您可以使用字符串占位符(%s),并在运行时使用java替换它们

<resources>
<string name="button_text">Add item</string>
<string name="message_text">Custom text %s </string>
</resources>

在Java中

String final = String.format(getString(R.string.message_text),getString(R.string.button_text));

然后将它设置到它使用字符串的地方

我已经创建了一个小库,允许您在构建时解析这些占位符,因此您不必添加任何Java/Kotlin代码来实现您想要的结果。

基于你的例子,你必须像这样设置你的字符串:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="button_text">Add item</string>
    <string name="message_text">You don't have any items yet! Add one by pressing the ${button_text} button.</string>
</resources>

然后插件将负责生成以下内容:

<!-- Auto generated during compilation -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="message_text">You don't have any items yet! Add one by pressing the Add item button.</string>
</resources>

它也适用于本地化和风味字符串,生成的字符串将保持自己更新,每当你改变你的模板或它的值。

更多信息请访问:https://github.com/LikeTheSalad/android-stem

使用新的数据绑定,您可以在xml中进行连接和更多操作。

例如,如果你有message1和message2,你可以:

android:text="@{@string/message1 + ': ' + @string/message2}"

你甚至可以导入一些文本utils并调用String。格式和朋友。

不幸的是,如果您想在多个地方重用它,它可能会变得混乱,您不希望这些代码片段到处都是。你不能在一个地方用xml定义它们(我不知道) 因此,你可以创建一个类来封装这些组合:

public final class StringCompositions {
    public static final String completeMessage = getString(R.string.message1) + ": " + getString(R.string.message2);
}

然后您可以使用它(您将需要导入带有数据绑定的类)

android:text="@{StringCompositions.completeMessage}"

除了以上Francesco Laurita的回答https://stackoverflow.com/a/39870268/9400836

似乎有一个编译错误“&entity被引用,但未声明”,可以通过引用外部声明来解决,就像这样

res - raw entities耳鼻喉科。

<!ENTITY appname "My App Name">

res /价值/ strings.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
    <!ENTITY appname SYSTEM "/raw/entities.ent">
]>
<resources>
    <string name="app_name">&appname;</string>
</resources

虽然它编译和运行,但它有一个空值。也许有人知道怎么解决。我会发表评论,但最低声誉是50。

我认为你不能。但是你可以根据自己的喜好“格式化”字符串:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="button_text">Add item</string>
    <string name="message_text">You don't have any items yet! Add one by pressing the %1$s button.</string>
</resources>

在代码中:

Resources res = getResources();
String text = String.format(res.getString(R.string.message_text),
                            res.getString(R.string.button_text));