SharedPreferences und Fragment Update

Hallo Zeige bitte nochmal wie du Werte in die prefs speicherst. Wenn ein User etwas ändert.
Interessent ist wie du auf die SharedPreferences kommst.

Dann zeige wie du die SharedPreferences holst um das Reset durchzuführen.

Ist das wirklich ein und die selbe Dadei in deinem APP Verzeichnis? Habe ich schon mal gefragt. Post Nr 5

Auch wichtig ist wie du SharedPreferences holst um aus ihr zu lesen.
Wenn ich mich richtig an deinen ersten Code erinnere waren das zwei verschiedene. Varianten.
Können somit auch zwei Datein Sein . Schaut mir auch sehr danach aus.


Würde gern die metohde aus der singelton Klasse sehen. Mich interessiert wie du die ref auf die SharedPreferences holst bekommst.

Das nur im textwatcher zu beobachten hilft dir wenig wenn es wirklich zwei pref datein im App Ordner oder sogar in verschiedenen Ordnern sind.
 
Zuletzt bearbeitet:
Damit du es verstehst.

In deiner „CategoryFragment“ Klasse beim Reset
Holst du die SharedPreferences so über den PreferenceManager
Code:
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());



In den anderen Kassen so.
Code:
pagesViewModel = PagesViewModel.getSingeltonInstance(getBaseContext());
sharedPreferences = pagesViewModel.getSharedPreferences();
wie das in der Klasse PagesViewModel. Und wie es in der Methode getSharedPreferences() aussieht wissen wir nicht den Code haben wir nicht. Nur Du.

Auch nicht ganz richtig und klar ist.

Code:
public void ObserveUiOnChange(EditText editText){
    editText.setText(singeltonInstance.sharedPreferences.getString(editText.getResources().getResourceEntryName(editText.getId()), ""));

}
Wo ist die Variable “singeltonInstance“ erstellt das ist dann wohl die dritte Datei die du erstellt hast?

Du solltest dich in deinem Programm für eine Art entscheiden damit du immer die gleiche Datei hast.
Den Sigelton dafür hast du ja schon also benutze ihn auch überall. Und mache nicht zwei vermiedene Sachen.


Obwohl der Ansatz zu gar nicht verkehrt sein könnte... das würde erklären warum BeforeTextChanged und AfterTextChanged (ich sag mal) verdrehte Werte liefert.
Das hat mit dem commit nicht zu tuhn. auch nicht mit der SharedP.

TextWatcher | Android Developers
 
Zuletzt bearbeitet:
Guten Morgen...

ich fang mal mit den Prefs an... ich gebe dir Recht, der Ursprung war sehr undurchsichtig... in Post 6 hatte ich das aber schon korrigiert
überall wird nun PreferenceManager.getDefaultSharedPreferences(MyApplication.getContext()) aufgerufen.

Nutzereingaben werden durch den TextWatcher nach jedem Tastendruck in die Prefs gespeichert.... das passiert in der singeltonInstance von PagesViewModel

Java:
public class PagesViewModel {

    private static PagesViewModel singeltonInstance;
    private SharedPreferences sharedPreferences;
    private Map<View, ReallySave> onExitSaveList = new HashMap<>();

    public static final String EDIT_TEXT_WIDGET = "android.support.design.widget.TextInputEditText";
    public static final String EDIT_TEXT_COMPAT = "android.support.v7.widget.AppCompatEditText";
    public static final String EDIT_TEXT = "android.widget.EditText";
    public static final String SWITCH = "android.widget.Switch";
    public static final String SWITCH_COMPAT = "android.support.v7.widget.SwitchCompat";

    private PagesViewModel(){}

    /**
     * Gibt immer die selbe Instanz von PagesViewModel zurück
     * @return PagesViewModel
     */
    public static PagesViewModel getSingeltonInstance() {
        if (singeltonInstance == null)
            singeltonInstance = new PagesViewModel();

        singeltonInstance.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MyApplication.getContext());
        return singeltonInstance;
    }

    /**
     * Registriert Steuerelemente um dessen Werte zu verarbeiten.
     *
     * @param uiElement Unterstützt wird EditText.
     * @return boolean Liefert FALSE wenn kein Context vorhanden ist.
     */
    public boolean ObserveUiOnChange(View uiElement) {
        helper(uiElement, true);
        return true;
    }

    /**
     * Lädt Daten aus Preferences in das übergebene Control und aktiviert bei Bedarf einen Listener
     * @param uiElement
     * @param setListener
     */
    private void helper(View uiElement, boolean setListener){
        switch (uiElement.getClass().getName()){
            case EDIT_TEXT_WIDGET:
            case EDIT_TEXT_COMPAT:
            case EDIT_TEXT:
                setEditText(uiElement);
                if (setListener)setEditTextListener(uiElement);
                break;

            case SWITCH:
            case SWITCH_COMPAT:
                setToggleState(uiElement);
                if (setListener)setToggleListener(uiElement);
                break;

                // TODO: Erweitern

            default:
                Log.i("VIEW_MODEL", "View-Element '"+uiElement.getClass().getName()+"' nicht unterstützt");
        }
    }

    /**
     * Nimmt Werte aus dem übergebenen Control und sicherte diesen in den Preferences
     * @param uiElement View: aktuell EditText und Switch
     */
    private void saver(View uiElement){
        switch (uiElement.getClass().getName()){
            case EDIT_TEXT:
                saveEditText(uiElement);
                break;

            case SWITCH:
            case SWITCH_COMPAT:
                saveToggleState(uiElement);
                break;

                // TODO: Erweitern
        }
    }

    /**
     * Registriert eine Element für eine Speicherung der Werte beim Beenden der Preferences.
     * @param uiElement View - Element
     */
    public void saveOnExit(View uiElement){
        saveOnExit(uiElement, new ReallySave(true));
    }

    /**
     * Registriert eine Element für eine Speicherung der Werte beim Beenden der Preferences.
     * @param uiElement View - Element
     * @param really ReallySave - Ein Boolisches Objekt über das registriert wird ob später eine Speicherung wirklich stattfinden soll.
     */
    public void saveOnExit(View uiElement, ReallySave really){
        onExitSaveList.put(uiElement, really);
        helper(uiElement, false);
    }

    /**
     * Speichert beim verlassen registrierte Werte.
     */
    public void save(){
        for (HashMap.Entry<View, ReallySave> entry : onExitSaveList.entrySet()){
            // TODO: Save Preferences
            if (entry.getValue().isState()) saver(entry.getKey());
        }
        onExitSaveList.clear();
    }

    /**
     * Fügt einen TextChangedListener hinzu und speichert so in Preferences.
     *
     * @param uiElement View
     */
    private static void setEditTextListener(View uiElement) {
        final EditText editText = (EditText)uiElement;

        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                Log.d("PAGES_VIEW_MODEL", "BeforeTextChanged "+editText.getResources().getResourceName(editText.getId()) + " " + editText.getText().toString());
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void afterTextChanged(Editable editable) {
                Log.d("PAGES_VIEW_MODEL", "AfterTextChanged "+editText.getResources().getResourceName(editText.getId()) + " " + editText.getText().toString());
                saveEditText(editText);
            }
        });
    }

    /**
     * Fügt einen OnCheckedChangeListener hinzu und speichert so in Preferences.
     *
     * @param uiElement View
     */
    private static void setToggleListener(View uiElement){
        CompoundButton compoundButton = (CompoundButton)uiElement;
        compoundButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                saveToggleState(compoundButton);
            }
        });
    }

    /**
     * Setzt Text aus Preferences in das Steuerelement
     * @param uiElement View
     */
    private static void setEditText(View uiElement) {
        EditText editText = (EditText)uiElement;
        editText.setText(singeltonInstance.sharedPreferences.getString(editText.getResources().getResourceEntryName(editText.getId()), ""));
    }

    /**
     * Setzt boolischen String Wert als boolean in das Steuerelement
     * @param uiElement View
     */
    private static void setToggleState(View uiElement) {
        CompoundButton compoundButton = (CompoundButton)uiElement;
        boolean b = Boolean.parseBoolean(singeltonInstance.sharedPreferences.getString(compoundButton.getResources().getResourceEntryName(compoundButton.getId()), "false"));
        compoundButton.setChecked(b);
    }

    /**
     * Speichert den Text eines Controls anhand seiner ID in den Preferences
     *
     * @param uiElement
     */
    private static void saveEditText(View uiElement){
        EditText editText = (EditText)uiElement;
        singeltonInstance.sharedPreferences
                .edit().putString(
                        editText.getResources().getResourceEntryName(editText.getId()),
                        editText.getEditableText().toString()
                ).apply();
    }

    /**
     * Speichert den Status eines Klickbaren Controls
     *
     * @param uiElement
     */
    private static void saveToggleState(View uiElement){
        CompoundButton compoundButton = (CompoundButton)uiElement;
        singeltonInstance.sharedPreferences
                .edit().putBoolean(
                        compoundButton.getResources().getResourceEntryName(compoundButton.getId()),
                        compoundButton.isChecked()
                ).apply();
    }

    /**
     * Boolische Erweiterung um Wert als Referenz zu erhalten.
     */
    public static class ReallySave{

        private boolean state;

        /**
         * Default ist FALSE.
         */
        public ReallySave(){
            this.state = false;
        }

        public ReallySave(boolean state){
            this.state = state;
        }

        public boolean isState() {
            return state;
        }

        public void setState(boolean state) {
            this.state = state;
        }
    }
 
Zuletzt bearbeitet:
wenn außerhalb der Kasse

PreferenceManager.getDefaultSharedPreferences(MyApplication.getContext())

benutzt und in der Klasse

singeltonInstance.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(BraesidentApplication.getContext());

sind das immer noch zwei paar Schuhe

in der klasse benutzt du auch einen anderen Kontext.
den Kontext der Activity würde ich in der klasse halten und auch über eine Metohdean die Kklasse Übergeben in der Activity .
 
Hmmm mein Fehler... da ich hier in 2 Projekten arbeite hab ich ein Kopierfehler gemacht... Es sind in einem Projekt immer die selben Context Aufrufe. Ich werde das oben im Code korrigieren.

Ich hab dir mal ein Link geschickt von einem sauberen Projekt das sich nur um dieses Thema dreht
 
sorry war falsch
 
Zuletzt bearbeitet:
Hallo habe mich der Sache noch mal angenommen und mir auch dein Zip File was du mir geschickt hast angesehen.

Gut am Anfang würde ich sagen lag es auch an den SharedPref Dateien. Den da ging es ja auch nicht nach einem Neustart der App. Jetzt benutzt du auch einen einheitlichen Context.

An deinem neu hinzugefügten Textwatcher liegt es auch nicht, der ist in dem Zip auch nicht zu sehen.

Das ganze liegt an dem verhalten des ViewPager. Der Pager ermöglicht es ja schnell von einem zum anderen Fragment zu Swipen. Damit das auch schnell gehen kann macht der Pager eines er lädt die benachbarten Fragmente schon vor in den Speicher ohne das sie angezeigt werden. Das Layout der Nachbarfragmente ist also schon geladen wenn geswipt wird, es gibt ja auch einen Zeitpunkt an dem beide Fragmente zu hälfte sichtbar sind also muss es schon geladen sein.
Zu dem Zeitpunkt wo du auf deinen Reset Button klickst ist das Fragment schon fertig geladen und die Methode „onCreateView() „ des NachbarFragments wird beim sichtbar werden gar nicht mehr durchlaufen.

Da du nur drei Fragmente hast sind die fast immer im Speicher. Wen eines angezeigt wird, wird kurz danach der Nachbar neugeladen.

Das kannst du nicht abschalten die minimale anzahlt der Fragmente die vorgeladen werden ist 1. 0 geht nicht, also sind immer beide Nachbarn geladen.

Da es ja nur ein Notfall Resset sein soll würde ich die Activity schlissen und wieder neu Starten. Das andere geht ja wie du sagt.

Oder eine etwas aufwendigere Variante

Fragment Refresh
ViewPager with FragmentPagerAdapter | CodePath Android Cliffnotes
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Braesident
Danke das du dich dem angenommen hast.

Ich starte erstmal die Activity neu. Wobei die beiden Links recht Interessant sind.

Der TextWatcher ist in der PagesViewModel.setEditTextListener()
 

Ähnliche Themen

D
Antworten
9
Aufrufe
1.769
jogimuc
J
M
  • MikelKatzengreis
Antworten
5
Aufrufe
135
swa00
swa00
J
  • Juleru
Antworten
8
Aufrufe
497
Juleru
J
Zurück
Oben Unten