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 : 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();
    }
 
}
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
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 : 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();
        }
    }
 
}
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
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 : 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);
    }
 
}
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
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 : 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();
    }
 
}
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 !