Utilisation d'un ViewModel avec SharedPreferences
Bonjour à tous,
Je travail actuellement sur un nouvelle application, et j'aimerai de ce fait, intégrer les ViewModel avec les LiveData. J'ai été lire pas mal de choses à ce sujet, mais je ne suis pas sûr de l'intégrer correctement.
J'ai commencé par créer les paramètres liés à mon application, je me suis basé sur la class suivante https://gist.github.com/idish/f46a83...3a5bda31078c95 pour avoir des SharedPreferences en LiveData.
Voici mes différentes class :
La class qui utilise les préférences partagées en LiveData :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| abstract class SharedPreferenceLiveData<T> extends LiveData<T> {
SharedPreferences sharedPrefs;
String key;
public T defValue;
public SharedPreferenceLiveData(SharedPreferences prefs, String key, T defValue) {
this.sharedPrefs = prefs;
this.key = key;
this.defValue = defValue;
}
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (SharedPreferenceLiveData.this.key.equals(key)) {
setValue(getValueFromPreferences(key, defValue));
}
}
};
abstract T getValueFromPreferences(String key, T defValue);
@Override
protected void onActive() {
super.onActive();
setValue(getValueFromPreferences(key, defValue));
sharedPrefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
}
@Override
protected void onInactive() {
sharedPrefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
super.onInactive();
}
} |
La class des préférences partagées LiveData boolean :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| public class SharedPreferenceBooleanLiveData extends SharedPreferenceLiveData<Boolean>{
public SharedPreferenceBooleanLiveData(SharedPreferences prefs, String key, Boolean defValue) {
super(prefs, key, defValue);
}
@Override
Boolean getValueFromPreferences(String key, Boolean defValue) {
return sharedPrefs.getBoolean(key, defValue);
}
} |
L'activité que gère les fragment de paramètres :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, SettingsFragmentWithViewModel.newInstance()).commitNow();
}
}
} |
Un de mes Fragments de paramètre :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class SettingsFragmentWithViewModel extends Fragment implements View.OnClickListener {
private Switch switchUseLogFile = null;
private SettingsViewModel viewModel;
public static SettingsFragmentWithViewModel newInstance() {
return new SettingsFragmentWithViewModel();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewModel = new ViewModelProvider(this, new SettingsViewModelFactory(PreferenceManager.getDefaultSharedPreferences(getContext()))).get(SettingsViewModel.class);
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_settings, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
switchUseLogFile = view.findViewById(R.id.setting_device_log_file_value);
viewModel.getLogFileEnable().observe(getViewLifecycleOwner(), new Observer<Boolean>() {
@Override
public void onChanged(Boolean islogFileEnable) {
// update UI
switchUseLogFile.setChecked( (islogFileEnable==true) ? true : false );
Toast.makeText(getContext(), "LogFile state : "+((islogFileEnable==true) ? "true" : "false"), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onClick(View view) {
Activity activity = getActivity();
switch (view.getId()){
case R.id.setting_device_log_file_value:
viewModel.setLogFileEnable(!switchUseLogFile.isChecked());
Toast.makeText(getContext(), "Change logFile switch", Toast.LENGTH_SHORT).show();
break;
}
}
} |
Mon ViewModel pour tout les fragments de paramètres :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class SettingsViewModel extends ViewModel {
private PreferencesManager prefManager;
private SharedPreferenceBooleanLiveData logFileEnable;
public SettingsViewModel(SharedPreferences preferences) {
this.prefManager = new PreferencesManager(preferences);
}
public SharedPreferenceBooleanLiveData getLogFileEnable() {
if (logFileEnable == null) {
logFileEnable = new SharedPreferenceBooleanLiveData(prefManager.getSharedPreferences(), PreferencesManager.PREF_LOG_FILE, false);
}
return logFileEnable;
}
public boolean setLogFileEnable(boolean b){
return prefManager.setEnableLogFile(b);
}
} |
Le Factory de mon ViewModel :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| public class SettingsViewModelFactory implements ViewModelProvider.Factory {
private SharedPreferences mPreferences;
public SettingsViewModelFactory(SharedPreferences preferences) {
mPreferences = preferences;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new SettingsViewModel(mPreferences);
}
} |
Et enfin, mon gestionnaire des préférences partagées :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public class PreferencesManager {
public static final String PREF_LOG_FILE = "use_log_file";
private SharedPreferences preferences = null;
public PreferencesManager(Context context) {
this.preferences = PreferenceManager.getDefaultSharedPreferences(context);
}
public PreferencesManager(SharedPreferences preferences) {
this.preferences = preferences;
}
public SharedPreferences getSharedPreferences(){
return preferences;
}
public boolean isLogFileEnable(){
return preferences.getBoolean(PREF_LOG_FILE, false);
}
public boolean setEnableLogFile(boolean b){
if(preferences==null)
return false;
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(PREF_LOG_FILE, b);
return editor.commit();
}
} |
Est ce que ma manière de faire est la bonne ?
Et est ce que le fait d'utiliser un ViewModel pour 4 Fragments de paramètres est une bonne chose, ou je dois en faire un pour chaque Fragment ?
Merci d'avance pour vos réponses !