Preferenze condivise Android in Fragment


90

Sto cercando di leggere SharedPreferences all'interno di Fragment. Il mio codice è ciò che utilizzo per ottenere le preferenze in qualsiasi altra attività.

     SharedPreferences preferences = getSharedPreferences("pref", 0);

Ottengo errore

    Cannot make a static reference to the non-static method getSharedPreferences(String, int) from the type ContextWrapper    

Ho provato a seguire questi collegamenti ma senza fortuna accedendo a SharedPreferences tramite metodi statici e Static SharedPreferences . Grazie per qualsiasi soluzione.

Risposte:


254

Il metodo getSharedPreferencesè un metodo Contextdell'oggetto, quindi la chiamata a getSharedPreferences da a Fragmentnon funzionerà ... perché non è un Context! (Activity è un'estensione di Context, quindi possiamo chiamare getSharedPreferences da esso).

Quindi devi ottenere le tue applicazioni Context da

// this = your fragment
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);

1
getSharedPreferences ("pref", 0); zero (0) significa cosa privato / pubblico?
Kailas

@Kailas corretto, la modalità, cioè WORLD_READABLE ect. developer.android.com/reference/android/content/… , int)
Jug6ernaut

5
0 è analogo a MODE_PRIVATE (o Context.MODE_PRIVATE se utilizzato all'interno di una classe che non è un'estensione di Context, come un frammento). Significa che solo l'app in questione può accedere alle preferenze. Non dovresti usare WORLD_READABLE o WORLD_WRITEABLE poiché sono deprecati nell'API 17+, per non parlare di una minaccia alla sicurezza.
Ankit Aggarwal

1
questa thisparola chiave è necessaria quando si esegue this.getActivity().getShared..?
Subby

2
@Subby no, chiamare esplicitamente solo "questo" non è mai necessario. L'ho fatto per preferenza personale poiché odio le chiamate di metodo ambigue. L'unica volta che "this" è richiesto è quando si tenta di accedere a un oggetto genitore non statico quando ci si trova fuori dal suo ambito di applicazione in una classe / interfaccia interna anonima.
Jug6ernaut

13

La risposta contrassegnata non ha funzionato per me, ho dovuto usare

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());

MODIFICARE:

Oppure prova a rimuovere this:

SharedPreferences prefs = getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);

8
La risposta contrassegnata non ha funzionato per te perché stai accedendo alle preferenze condivise predefinite. Un design migliore è memorizzare le tue preferenze non come un oggetto condiviso ma in uno spazio separato e privato, che è ciò di cui si tratta qui la domanda e la risposta.
zeeshan

8

Come nota di cautela questa risposta fornita dall'utente sopra di me è corretta.

SharedPreferences preferences = this.getActivity().getSharedPreferences("pref",0);

Tuttavia, se si tenta di ottenere qualcosa nel frammento prima che onAttach venga chiamato getActivity () restituirà null.


3

È possibile effettuare la SharedPrefencesin onAttachmodalità di frammento in questo modo:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    SharedPreferences preferences = context.getSharedPreferences("pref", 0);
}


1

getActivity()e non onAttach()mi hai aiutato nella stessa situazione
forse ho fatto qualcosa di sbagliato
ma! Ho trovato un'altra decisione
Ho creato un campo Context thisContextall'interno del mio Fragment
E ho ottenuto un contesto corrente dal metodo onCreateView
e ora posso lavorare con la pref condivisa dal frammento

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {   
...   
thisContext = container.getContext();   
...   
}

1

Per definire la preferenza in Fragment: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR",Context.MODE_PRIVATE); editor.putString("credi_credito",cre); editor.commit();

Per chiamare un'altra attività o frammentare i dati delle preferenze: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR", Context.MODE_PRIVATE); credit=pref.getString("credi_credito",""); if(credit.isNotEmpty)...


0

È possibile ottenere un contesto dall'interno di un file Fragment

Basta fare

public class YourFragment extends Fragment {

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        final View root = inflater.inflate(R.layout.yout_fragment_layout, container, false);
        // get context here
        Context context = getContext();
        // do as you please with the context


        // if you decide to go with second option
        SomeViewModel someViewModel = ViewModelProviders.of(this).get(SomeViewModel.class);
        Context context = homeViewModel.getContext();
        // do as you please with the context
        return root;
    }
}

È inoltre possibile allegare un AndroidViewModelnel onCreateViewmetodo che implementa un metodo che restituisce il contesto dell'applicazione

public class SomeViewModel extends AndroidViewModel {

    private MutableLiveData<ArrayList<String>> someMutableData;
    Context context;

    public SomeViewModel(Application application) {
        super(application);
        context = getApplication().getApplicationContext();
        someMutableData = new MutableLiveData<>();
        .
        .
     }

     public Context getContext() {
         return context
     }
  }

0

Forse questo è utile per qualcuno dopo pochi anni. Un nuovo modo, su Androidx, di entrare SharedPreferences()nel frammento è implementarlo ingradle dependencies

implementation "androidx.preference:preference:1.1.1"

e poi, chiamata all'interno del frammento

SharedPreferences preferences;
preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(getActivity());
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.