java - 使用默认语言以外的其他语言时,不要连接 setText 显示的文本问题 + 应用程序崩溃

标签 java android xml string concatenation

我已经在 strings.xml 中定义了字符串(以及其他语言的相应文件)。

当应用程序执行这一行时(不仅仅是这一行,其他人也喜欢这一行): timeTextView.setText(substr2 + ""+ getString(R.string.shours) + ""+ 分钟实数 + ""+ getString(R.string.sminutes));

在默认(英语)语言下,屏幕上的结果是可以的!但是,如果我更改手机上的语言并尝试使用该应用程序,则一切正常,直到我单击按钮(应显示结果时),然后应用程序崩溃。

我在 stackoverflow 上进行了搜索(不仅如此),但我不知道如何解决该问题。

values\strings.xml 中定义的字符串:

<string name="shours">hour(s),</string>
<string name="sminutes">minute(s)</string>

我已经尝试过:

timeTextView.setText(getString(substr2, R.string.shours, minutereal, R.string.sminutes));

但是这个根本不起作用。

这个:

timeTextView.setText(substr2 + " stunde(n), " + minutereal + "  minute(n)");

与第一个选项一样有效,但结果相同,适用于默认语言,并且作为第一个选项,我收到相同的警告:不要连接 setText 问题显示的文本。

logcat 崩溃:

08-21 16:21:02.834 23866-23866/com.example.android.test_app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.test_app, PID: 23866
java.lang.StringIndexOutOfBoundsException: length=4; regionStart=0; regionLength=-1
at java.lang.String.startEndAndLength(String.java:504)
at java.lang.String.substring(String.java:1333)
at com.example.android.test_app.MainActivity.displayTimeReal(MainActivity.java:91)
at com.example.android.test_app.MainActivity.access$200(MainActivity.java:12)
at com.example.android.test_app.MainActivity$1.onClick(MainActivity.java:31)
at android.view.View.performClick(View.java)
at android.view.View$PerformClick.run(View.java)
at android.os.Handler.handleCallback(Handler.java)
at android.os.Handler.dispatchMessage(Handler.java)
at android.os.Looper.loop(Looper.java)
at android.app.ActivityThread.main(ActivityThread.java)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)

所以,正如我之前所说,我已经在寻找答案,这并不是因为我懒惰或其他什么,而是我只是不明白......(也许是愚蠢的:P)。

这是插入数据并按下按钮后应显示在屏幕上的值之一的完整脚本:

private void displayTimeReal(double timpreal) {
    DecimalFormat formattr = new DecimalFormat();
    formattr.setMaximumFractionDigits(2);
    String formattedTimpR = formattr.format(timpreal);
    String substr1 = formattedTimpR.substring(formattedTimpR.indexOf(".") + 1); //decimals
    String substr2 = formattedTimpR.substring(0, formattedTimpR.indexOf(".")); //unit
    double minutereal = Double.parseDouble(substr1);
    minutereal = minutereal * 0.6;
    TextView timeTextView = (TextView) findViewById(R.id.rezultat_ore_real);
    timeTextView.setText(substr2 + " " + getString(R.string.shours) + " " + minutereal + " " + getString(R.string.sminutes));
    //timeTextView.setText(getString(substr2, R.string.shours, minutereal, R.string.sminutes));

任何帮助将不胜感激!!!

感谢您的宝贵时间以及您永无休止的(希望:P)耐心和支持!

附注发挥魔力的按钮:

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:id="@+id/butto"
        android:onClick="onClick"
        android:text="@string/sbutton"
        android:textColor="#0277BD"
        android:textStyle="bold" />

以及要显示的整个内容:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    findViewById(R.id.butto)
            .setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    displayTarget((procente / Double.parseDouble(((EditText) findViewById(R.id.vZeit))
                            .getText().toString())) * mitarbeiter);
                    displayTime((Double.parseDouble(((EditText) findViewById(R.id.aufGesSt))
                            .getText().toString())) / (procente / Double.parseDouble(((EditText) findViewById(R.id.vZeit))
                            .getText().toString()) * mitarbeiter));
                    displayTimeReal((Double.parseDouble(((EditText) findViewById(R.id.aufGesSt))
                            .getText().toString())) / (procente / Double.parseDouble(((EditText) findViewById(R.id.vZeit))
                            .getText().toString()) * mitarbeiter));

                }
            });
}

最佳答案

问题第二部分的答案(使用默认语言以外的其他语言时应用程序崩溃)已在此处解决:

Android app crashes if installed as apk, works if runned trough Android Studio

答案由用户 samgak 提供:

该问题似乎是由于设备的区域设置不同而导致数字格式不同所致。

当您使用 DecimalFormat 对象时,小数点分隔符会根据设备的语言设置而有所不同。例如,在英语中,它是一个点,例如3.14159 但在德语中它是一个逗号,例如3,14159。

这会导致问题,因为当您调用indexOf()时,您的代码总是在寻找点。

您可以通过多种方式解决此问题。一种方法是在创建 DecimalFormat 对象时指定区域设置,例如:

NumberFormat nf = NumberFormat.getNumberInstance(Locale.ENGLISH);
DecimalFormat formattr = (DecimalFormat)nf;

或者您可以只设置小数点分隔符:

DecimalFormat formattr = new DecimalFormat(); formattr.setDecimalSeparator('.'); 然而,也许您希望它对德国用户显示不同。在这种情况下,您可以更改检查点的代码以检查正确的字符是什么:

String zecimaleTimpReal = formattedTimpR.substring(formattedTimpR.indexOf("" + formattr.getDecimalFormatSymbols().getDecimalSeparator()) + 1);

添加到空字符串只是从 char 转换为 String 的一个技巧。

请注意,还有一个“分组符号”,也可以是逗号或点,例如123,456.78。您可能想要禁用分组,如下所示:

formattr.setGroupingUsed(false);

@samgak - 再次感谢您!

关于java - 使用默认语言以外的其他语言时,不要连接 setText 显示的文本问题 + 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39082582/

相关文章:

javax.el.PropertyNotFoundException : Property 'role_id' not found on type model. 角色

java - 代码优化建议

java - 为什么 toArray 的 <T> 隐藏了 Collection<E> 的 <E>?

python - 人机可读——文件中的结构化数据存储

java创建float[]的问题

android - View 模型中的实时数据只能在一个地方观察到吗?

android - 无法确定任务 ':app:mergeDebugAssets' 的依赖关系

java - AppCompatActivity 中的 GoogleMap 对象为 null

xml - 如何在 XSLT 1.0 中迭代 IDREFS 值?

Android自定义EditText View 和NextFocusDown