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 :
La class des préférences partagées LiveData boolean :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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(); } }
L'activité que gère les fragment de paramètres :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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); } }
Un de mes Fragments de paramètre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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(); } } }
Mon ViewModel pour tout les fragments de paramètres :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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; } } }
Le Factory de mon ViewModel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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); } }
Et enfin, mon gestionnaire des préférences partagées :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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); } }
Est ce que ma manière de faire est la bonne ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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(); } }
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 !
Partager