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

时间:2016-08-22 14:48:20

标签: java android xml string concatenation

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

当应用程序执行此行时(而不仅仅是那一行,其他人就像这一行):     timeTextView.setText(substr2 +"" + getString(R.string.shours)+"" + minutereal +"" + 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)的耐心和支持!

P.S。执行魔术的按钮:

<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));

                }
            });
}

1 个答案:

答案 0 :(得分:0)

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

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

答案由用户samgak提供:

问题似乎是由于数字的格式因设备的Locale而异。

使用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 - 再次感谢你!