Sprache(Locale) ändern durch Menüauswahl

  • Antworten:29
  • OffenNicht stickyNicht beantwortet
  • Forum-Beiträge: 21

10.09.2014, 15:50:52 via Website

Hallo, also ich hab meine app mit verschiedenen strings erstellt (/res/values-de/strings.xml; /values-zh/strings.xml.
jetzt habe ich eine SettingsActivity und in der befindet sich ein Auswahlfeld um eine Sprache auszuwählen. Wenn der User jetzt auf Deutsch klickt, soll die App die deutschen strings abrufen. wie löse ich das am besten?
btw: ich arbeite mit fragments, und die settingsActivity ist eine eigene activity und keine fragmentActivity. vllt ist das wichtig, lg

Antworten
  • Forum-Beiträge: 11.137

10.09.2014, 18:30:02 via App

Hallo Markus,
wenn du die Standart Locale benuzt wird die Android sprache benutzt. Reicht dir das nicht?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

10.09.2014, 19:43:02 via App

nein ich hätte gerne dass der user auswählen kann welche sprache die app haben soll

Antworten
  • Forum-Beiträge: 21

11.09.2014, 12:18:51 via Website

okay diesen code habe ich bereits gefunden:

Locale locale = new Locale("ru");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());

aber wo gehört der hin? und wie erkennt der code welche usereingabe gemacht wurde in der SettingsActivity? lg

Antworten
  • Forum-Beiträge: 11.137

11.09.2014, 13:18:43 via Website

Na das kommt darauf an, wie das Programmiert ist.
Ich hätte gesagt, wenn die Sprache als string reinkommt, muss du diese per ifs filtern und jeweils die abkürzung speichern.
Dann musst du bei new Locale() als Parameter nur deine Methode angeben, die die aktuell Eingestellte Sprachenabkürzung liefert.
Mehr aufwan ist das nicht.
Aber vlt. muss der Code beim Starten der App auch aufgerufen werden, denn es kann sein, dass die Einstellung dann nur für eine App Laufzeit gilt

LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 11.137

11.09.2014, 20:01:53 via App

Ja poste mal deinen Bisherigen teil der Einstellungen der Sprache.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

11.09.2014, 21:43:51 via App

ich habe bisher keine einstellungen, ur das menü mit den auswahlmöglichkeiten in der settingsActivity. standardsprache ist deutsch und sonst hab ich noch string dateien für die anderen sprachen.

Antworten
  • Forum-Beiträge: 11.137

11.09.2014, 22:05:49 via App

Ja dann halt mal den Code der Sprachauswahl.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

11.09.2014, 23:15:34 via Website

hier meine settingsActivity:

public class SettingsActivity extends PreferenceActivity {
    private static final boolean ALWAYS_SIMPLE_PREFS = false;
    Locale locale;

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        setupSimplePreferencesScreen();
    }

    @SuppressWarnings("deprecation")
    private void setupSimplePreferencesScreen() {
        if (!isSimplePreferences(this)) {
            return;
        }

        // In the simplified UI, fragments are not used at all and we instead
        // use the older PreferenceActivity APIs.

        // Add 'general' preferences.
        addPreferencesFromResource(R.xml.pref_general);

        // Add 'Cash-Game Ticker' preferences, and a corresponding header.
        PreferenceCategory fakeHeader = new PreferenceCategory(this);
        fakeHeader.setTitle(R.string.pref_header_cg_notifications);
        getPreferenceScreen().addPreference(fakeHeader);
        addPreferencesFromResource(R.xml.pref_cg_notification);

        // Add 'Tournament Ticker' preferences, and a corresponding header.
        PreferenceCategory fakeHeader2 = new PreferenceCategory(this);
        fakeHeader2.setTitle(R.string.pref_header_tm_notifications);
        getPreferenceScreen().addPreference(fakeHeader2);
        addPreferencesFromResource(R.xml.pref_tm_notification);

        // Bind the summaries of EditText/List/Dialog/Ringtone preferences to
        // their values. When their values change, their summaries are updated
        // to reflect the new value, per the Android Design guidelines.
        bindPreferenceSummaryToValue(findPreference("location_list"));
        bindPreferenceSummaryToValue(findPreference("language_list"));
        bindPreferenceSummaryToValue(findPreference("notifications_new_cg_ringtone"));
        bindPreferenceSummaryToValue(findPreference("notifications_new_tm_ringtone"));
    }

    /** {@inheritDoc} */
    @Override
    public boolean onIsMultiPane() {
        return isXLargeTablet(this) && !isSimplePreferences(this);
    }

    private static boolean isXLargeTablet(Context context) {
        return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
    }

    private static boolean isSimplePreferences(Context context) {
        return ALWAYS_SIMPLE_PREFS
                || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
                || !isXLargeTablet(context);
    }

    /** {@inheritDoc} */
    @Override
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void onBuildHeaders(List<Header> target) {
        if (!isSimplePreferences(this)) {
            loadHeadersFromResource(R.xml.pref_headers, target);
        }
    }

    /**
     * A preference value change listener that updates the preference's summary
     * to reflect its new value.
     */
    private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object value) {
            String stringValue = value.toString();

            if (preference instanceof ListPreference) {
                // For list preferences, look up the correct display value in
                // the preference's 'entries' list.
                ListPreference listPreference = (ListPreference) preference;
                int index = listPreference.findIndexOfValue(stringValue);

                // Set the summary to reflect the new value.
                preference
                        .setSummary(index >= 0 ? listPreference.getEntries()[index]
                                : null);

            } else if (preference instanceof RingtonePreference) {
                // For ringtone preferences, look up the correct display value
                // using RingtoneManager.
                if (TextUtils.isEmpty(stringValue)) {
                    // Empty values correspond to 'silent' (no ringtone).
                    preference.setSummary(R.string.pref_ringtone_silent);

                } else {
                    Ringtone ringtone = RingtoneManager.getRingtone(
                            preference.getContext(), Uri.parse(stringValue));

                    if (ringtone == null) {
                        // Clear the summary if there was a lookup error.
                        preference.setSummary(null);
                    } else {
                        // Set the summary to reflect the new ringtone display
                        // name.
                        String name = ringtone
                                .getTitle(preference.getContext());
                        preference.setSummary(name);
                    }
                }

            } else {
                // For all other preferences, set the summary to the value's
                // simple string representation.
                preference.setSummary(stringValue);
            }
            return true;
        }
    };

    private static void bindPreferenceSummaryToValue(Preference preference) {
        // Set the listener to watch for value changes.
        preference
                .setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);

        // Trigger the listener immediately with the preference's
        // current value.
        sBindPreferenceSummaryToValueListener.onPreferenceChange(
                preference,
                PreferenceManager.getDefaultSharedPreferences(
                        preference.getContext()).getString(preference.getKey(),
                        ""));
    }

    /**
     * This fragment shows general preferences only. It is used when the
     * activity is showing a two-pane settings UI.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static class GeneralPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.pref_general);

            // Bind the summaries of EditText/List/Dialog/Ringtone preferences
            // to their values. When their values change, their summaries are
            // updated to reflect the new value, per the Android Design
            // guidelines.
            bindPreferenceSummaryToValue(findPreference("example_text"));
            bindPreferenceSummaryToValue(findPreference("example_list"));
        }
    }

    /**
     * This fragment shows notification preferences only. It is used when the
     * activity is showing a two-pane settings UI.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static class NotificationPreferenceFragment extends
            PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.pref_cg_notification);

            // Bind the summaries of EditText/List/Dialog/Ringtone preferences
            // to their values. When their values change, their summaries are
            // updated to reflect the new value, per the Android Design
            // guidelines.
            bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
        }
    }

    /**
     * This fragment shows data and sync preferences only. It is used when the
     * activity is showing a two-pane settings UI.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static class DataSyncPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.pref_tm_notification);

            // Bind the summaries of EditText/List/Dialog/Ringtone preferences
            // to their values. When their values change, their summaries are
            // updated to reflect the new value, per the Android Design
            // guidelines.
            bindPreferenceSummaryToValue(findPreference("sync_frequency"));
        }
    }
}

und hier der teil der xml für die sprach auswahl:

<ListPreference
    android:defaultValue="en"
    android:entries="@array/pref_language_select"
    android:entryValues="@array/pref_language_values"
    android:key="language_list"
    android:negativeButtonText="@null"
    android:positiveButtonText="@null"
    android:title="@string/pref_title_language" />

— geändert am 11.09.2014, 23:16:22

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 09:34:52 via Website

Für das lesen des ausgeählten Eintrags:

ListPreference listPreference = (ListPreference) findPreference("language_list");
CharSequence currText = listPreference.getEntry();
String currValue = listPreference.getValue();

Wie sehen denn deine beiden Arrays der ListPreference aus?

Wenn ich jetzt annehme, dass der String currValue die Abkürzung der Sprache ist dann sieht der Code so aus:

ListPreference listPreference = (ListPreference) findPreference("language_list");
    CharSequence currText = listPreference.getEntry();
    String currValue = listPreference.getValue();

Locale locale = new Locale(currValue);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());

Jetzt musst du nur noch überprüfen, ob der Code mit allen abkürzungen Funktioniert und diesen an eine geeignete Stelle in den Einstellungen platzieren.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

12.09.2014, 11:49:57 via Website

hmm also ich bekomme fehlermeldungen von eclipse mit dem code.

hier mal meine arrays:

<string-array name="pref_language_select">
    <item>Deutsch</item>
    <item>English</item>
    <item>中文</item>
    <item>Espanol</item>

</string-array>
<string-array name="pref_language_values">
    <item>de</item>
    <item>en</item>
    <item>zh</item>
    <item>es</item>        
</string-array>

was wäre eine geeignete stelle für den code? lg

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 11:53:36 via Website

Ich würde in den Preferences mit einem PreferenceChange Listener machen, sodass dieser Code ausgeführt wirdwenn sich etwas ändert.
Welche Fehler werden denn angezeigt.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 12:20:27 via Website

Was steht denn im Log (LogCat)?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

12.09.2014, 16:51:48 via Website

ich schaffs nicht =( habs dann zwar ohne absturz geschafft aber es hat sich nichts geändert.

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 16:53:39 via Website

Wenn ich dir weiterhelfen soll, musst du das "schaffst nicht" genauer beschreiben.
nochmal: Welche Fehler werden denn im Log angezeigt?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

12.09.2014, 17:14:39 via Website

bin noch immer beim gleichen quelltext wie oben! hab es wieder rausgenommen da es nicht funktioniert hat

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 17:17:10 via Website

Warum willst du mir die Frage zum Log nicht beantworten?
Ohne kommt man kaum ans Ziel..

Also was steht da jetzt drinne?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

12.09.2014, 18:07:49 via Website

09-12 18:06:57.326: I/PersonaManager(25447): getPersonaService() name persona_policy
09-12 18:06:57.366: E/MoreInfoHPW_ViewGroup(25447): Parent view is not a TextView
09-12 18:06:57.496: I/Adreno-EGL(25447): <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: ()
09-12 18:06:57.496: I/Adreno-EGL(25447): OpenGL ES Shader Compiler Version: E031.24.00.08+13
09-12 18:06:57.496: I/Adreno-EGL(25447): Build Date: 03/20/14 Thu
09-12 18:06:57.496: I/Adreno-EGL(25447): Local Branch: 0320_AU200_patches
09-12 18:06:57.496: I/Adreno-EGL(25447): Remote Branch:
09-12 18:06:57.496: I/Adreno-EGL(25447): Local Patches:
09-12 18:06:57.496: I/Adreno-EGL(25447): Reconstruct Branch:
09-12 18:07:05.916: I/PersonaManager(25447): getPersonaService() name persona_policy
09-12 18:07:05.926: E/MoreInfoHPW_ViewGroup(25447): Parent view is not a TextView
09-12 18:07:05.966: W/dalvikvm(25447): threadid=1: thread exiting with uncaught exception (group=0x41793da0)
09-12 18:07:05.976: E/AndroidRuntime(25447): FATAL EXCEPTION: main
09-12 18:07:05.976: E/AndroidRuntime(25447): Process: at.co.ccc.mondel, PID: 25447
09-12 18:07:05.976: E/AndroidRuntime(25447): java.lang.RuntimeException: Unable to start activity ComponentInfo{at.co.ccc.mondel/at.co.ccc.mondel.SettingsActivity}: java.lang.NullPointerException
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2394)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2452)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.app.ActivityThread.access$900(ActivityThread.java:172)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1302)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.os.Handler.dispatchMessage(Handler.java:102)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.os.Looper.loop(Looper.java:136)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.app.ActivityThread.main(ActivityThread.java:5586)
09-12 18:07:05.976: E/AndroidRuntime(25447): at java.lang.reflect.Method.invokeNative(Native Method)
09-12 18:07:05.976: E/AndroidRuntime(25447): at java.lang.reflect.Method.invoke(Method.java:515)
09-12 18:07:05.976: E/AndroidRuntime(25447): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
09-12 18:07:05.976: E/AndroidRuntime(25447): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
09-12 18:07:05.976: E/AndroidRuntime(25447): at dalvik.system.NativeStart.main(Native Method)
09-12 18:07:05.976: E/AndroidRuntime(25447): Caused by: java.lang.NullPointerException
09-12 18:07:05.976: E/AndroidRuntime(25447): at at.co.ccc.mondel.SettingsActivity.setupSimplePreferencesScreen(SettingsActivity.java:36)
09-12 18:07:05.976: E/AndroidRuntime(25447): at at.co.ccc.mondel.SettingsActivity.onPostCreate(SettingsActivity.java:29)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.app.Instrumentation.callActivityOnPostCreate(Instrumentation.java:1156)
09-12 18:07:05.976: E/AndroidRuntime(25447): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
09-12 18:07:05.976: E/AndroidRuntime(25447): ... 11 more
09-12 18:07:08.586: I/Process(25447): Sending signal. PID: 25447 SIG: 9

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 18:12:14 via Website

Wen du jetzt noch deinen Log selber auswertest fängst du auch mehr damit an und musst nicht immer Fragen.

at at.co.ccc.mondel.SettingsActivity.setupSimplePreferencesScreen(SettingsActivity.java:36)
-> NullpointerException in Datei SettingsActivity.java Zeile 36

Was steht denn da (ab besten nen paar zeilen vorher mitkopieren)?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

12.09.2014, 18:23:38 via Website

private void setupSimplePreferencesScreen() {

        if (!isSimplePreferences(this)) {
            return;
        }
        ListPreference listPreference = (ListPreference) findPreference("language_list");
        CharSequence currText = listPreference.getEntry();
        String currValue = listPreference.getValue();
        Locale locale = new Locale(currValue);
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());

        // Add 'general' preferences.
        addPreferencesFromResource(R.xml.pref_general);

        // Add 'Cash-Game Ticker' preferences, and a corresponding header.
        PreferenceCategory fakeHeader = new PreferenceCategory(this);
        fakeHeader.setTitle(R.string.pref_header_cg_notifications);
        getPreferenceScreen().addPreference(fakeHeader);
        addPreferencesFromResource(R.xml.pref_cg_notification);

        // Add 'Tournament Ticker' preferences, and a corresponding header.
        PreferenceCategory fakeHeader2 = new PreferenceCategory(this);
        fakeHeader2.setTitle(R.string.pref_header_tm_notifications);
        getPreferenceScreen().addPreference(fakeHeader2);
        addPreferencesFromResource(R.xml.pref_tm_notification);

        // Bind the summaries of EditText/List/Dialog/Ringtone preferences to
        // their values. When their values change, their summaries are updated
        // to reflect the new value, per the Android Design guidelines.
        bindPreferenceSummaryToValue(findPreference("location_list"));
        bindPreferenceSummaryToValue(findPreference("language_list"));
        bindPreferenceSummaryToValue(findPreference("notifications_new_cg_ringtone"));
        bindPreferenceSummaryToValue(findPreference("notifications_new_tm_ringtone"));
    }

außerdem meldet eclipse currText is never used.

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 18:33:40 via Website

Es ist eine NullPointer Exception, da deine Preference nicht ausgelesen werden kann wenn noch garkeine Pref XML gesetzt ist.
So musst du diese Zeile :

addPreferencesFromResource(R.xml.pref_general);

über die Zeilen für das auslesen er Preference schreiben.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

12.09.2014, 19:17:04 via Website

jetzt funktionierts einigermaßen, jedoch übersetzt er nur den text der hinter der preference view steht, aber nicht den davor

darf ich dir mein project mal schicken? ;D

— geändert am 12.09.2014, 19:18:04

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 19:37:09 via Website

Am besten in eine static Methode einer Tools Klasse auslagern und dann nurncoh in jeder Activity eine Zeile aufrufen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

12.09.2014, 20:05:47 via Website

also ich bin komplett überfordert ;D ich habe eine settingsActivity in eclipse erstellen lassen, und diese einfach bearbeitet, deswegen verliere ich so schnell den faden in dem quelltext, weiß nicht genau was ich tun soll =(

Antworten
  • Forum-Beiträge: 11.137

12.09.2014, 20:12:37 via Website

Wie wäre es mal, mit einem Grundlagen Buch, da kannst du dann auch Beispiele nachproggen und so.
Überleg es dir, kann viel helfen :)

Also, das mit der settings Activity ist erstmal nicht so wichtig.
Du willst ja das die Sprache überall die gleiche ist,also musst du deine Code für die veränderung der Sprache in jede deiner Activities (ausserhalb von den Settings) einbauen.
Damit du nicht in jede Activity die gleichen 6 Zeilen Code einfügen musst, machst du die OOP und Methoden zu nutze und lagerst den Code in einer Klasse in einer Methode aus.
Dann musst du nur noch diese vorher Definierte Methode in jeder Activity aufrufen und hast nun nur 1 Zeile Code statt 5.

Jetzt verständlich?
Sonst einfach nochmal fragen.
Ist kein problem.
LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten