2
\$\begingroup\$

I'm taking and Android course and I would like to refactor the code for one of the exercises. The complete solution done by tutors is here.

When I was doing this exercise by myself I was annoyed by those ifs with instanceofs and by the fact that class containing too much logic.

Also, due to the fact this code used to be common at most apps, I think it should be moved to a different class.

This code set the summary of each preference in a preference screen (see the image below). To illustrate that, here is a picture from my phone running other simply preference screen.

I have created a simply factory class (SummaryResolverFactory) an interface (SummaryResolver) and a bunch of implementation for each type of Android preference type (ListPreferenceSummaryResolver, .

I couldn't eliminate the "instanceof ifs" it will be doing only once within factory class.

public interface SummarySetter {
    void setSummary(Object value);
}

public final class SummarySetterFactory {

    public static SummarySetter createFrom(Preference preference) {
        if (preference instanceof ListPreference) {
            return new ListPreferenceSummarySetter((ListPreference) preference);
        } else if (preference instanceof CheckBoxPreference) {
            return new CheckboxSummarySetter((CheckBoxPreference) preference);
        } else if (preference instanceof EditTextPreference) {
            return new EditTextSummarySetter((EditTextPreference) preference);
        } else if (preference instanceof SwitchPreferenceCompat) {
            return new EmptySummarySetter();
        }
        return new EmptySummarySetter();
    }

    private static class EmptySummarySetter implements SummarySetter {
        @Override
        public void setSummary(Object value) {
            throw new UnsupportedOperationException("not implemented yet");
        }
    }

}

public class CheckboxSummarySetter extends AbstractSummarySetter<CheckBoxPreference> {
    public CheckboxSummarySetter(CheckBoxPreference preference) {
        super(preference);
    }

    @Override
    public void setSummary(Object value) {

        /* does nothing. CheckboxSummary is setted automatically by its status and attribtes
        summaryOn and summaryOf from CheckBoxPreference;*/
    }
}




public class ListPreferenceSummarySetter extends AbstractSummarySetter<ListPreference> {
    private static final String TAG = "ListPreferenceSummarySe";

    public ListPreferenceSummarySetter(ListPreference preference) {
        super(preference);
    }

    @Override
    public void setSummary(Object value) {
        int index = preference.findIndexOfValue((String) value);
        if (index < 0) {
            return;
        }

        CharSequence summary = preference.getEntries()[index];
        preference.setSummary(summary);
    }
}

public class EditTextSummarySetter extends AbstractSummarySetter<EditTextPreference> {

    public EditTextSummarySetter(EditTextPreference preference) {
        super(preference);
    }

    @Override
    public void setSummary(Object value) {
        preference.setSummary((CharSequence) value);
    }
}
public class CheckboxSummarySetter extends AbstractSummarySetter<CheckBoxPreference> {
    public CheckboxSummarySetter(CheckBoxPreference preference) {
        super(preference);
    }

    @Override
    public void setSummary(Object value, Object defaultValue) {

        /* does nothing. CheckboxSummary is setted automatically by its status and attribtes
        summaryOn and summaryOf from CheckBoxPreference;*/
    }
}



public class SettingsFragment extends PreferenceFragmentCompat implements
        SharedPreferences.OnSharedPreferenceChangeListener {
    private static final String TAG = "SetttingsFragment";


    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.prefsunshine);
        Log.d(TAG, "onCreatePreferences: ");
        PreferenceScreen preferenceScreen = getPreferenceScreen();

        SharedPreferences sharedPreferences = preferenceScreen.getSharedPreferences();
        int preferenceCount = preferenceScreen.getPreferenceCount();

        for (int i = 0; i < preferenceCount; i++) {
            Preference preference = preferenceScreen.getPreference(i);
            setSummary(sharedPreferences, preference);
        }

    }

    private void setSummary(SharedPreferences sharedPreferences, Preference preference) {
        SummarySetter summarySetter = SummarySetterFactory.createFrom(preference);
        String value = sharedPreferences.getString(preference.getKey(), "");
        Log.d(TAG, "setSummary: "+value);
        summarySetter.setSummary(value);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        Log.d(TAG, "onSharedPreferenceChanged: "+key);
        Preference preference = findPreference(key);
        if (preference == null) {
            return;
        }

        setSummary(sharedPreferences, preference);
    }

    @Override
    public void onStart() {
        super.onStart();
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
}

ps. ListPreference, CheckBoxPreference, PreferenceFragmentCompat and other misses classes are Android SDK stuff.

enter image description here

Please, review my code about any aspects you think is relevant.

One question about performance: these object creation whenever user change a property is a risk to performance? I like this way of doing things (creating objects) I think in java this is not so problematic anymore. In Android maybe.

thanks in advance

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.