0

I'm confused about using Android Preferences with the Support v7 or v14 library. It seems like every couple of months Google changes the API.

I'm trying to create a Time Preference Dialog. However, my current one doesn't work with the Support Library.

public class TimePickerPreference : DialogPreference
{
    private int lastHour = 0;
    private int lastMinute = 0;
    private TimePicker picker = null;

    public static int GetHour(string time)
    {
        string[] pieces = time.Split(':');

        return Convert.ToInt32(pieces[0]);
    }

    public static int GetMinute(string time)
    {
        string[] pieces = time.Split(':');

        return Convert.ToInt32(pieces[1]);
    }

    public TimePickerPreference(Context ctxt, IAttributeSet attrs) : base(ctxt, attrs)
    {
    }   

    protected override View OnCreateDialogView()
    {
        picker = new TimePicker(Context);
        picker.SetIs24HourView(Java.Lang.Boolean.True);
        return picker;
    }

    protected override void OnBindDialogView(View v)
    {
        base.OnBindDialogView(v);

        picker.Hour = lastHour;
        picker.Minute = lastMinute;
    }


    protected override void OnDialogClosed(bool positiveResult)
    {
        base.OnDialogClosed(positiveResult);

        if (positiveResult)
        {
            lastHour = picker.Hour;
            lastMinute = picker.Minute;

            string time = lastHour + ":" + lastMinute;
            if (lastMinute.ToString().Length == 1)
                time = lastHour + ":" + "0" + lastMinute;

            if (CallChangeListener(time))
            {
                PersistString(time);
            }

            Title = "שעת תזכורת: " + time;
        }
    }

    protected override Java.Lang.Object OnGetDefaultValue(TypedArray a, int index)
    {
        return a.GetString(index);
    }

    protected override void OnSetInitialValue(bool restorePersistedValue, Java.Lang.Object defaultValue)
    {
        string time = string.Empty;

        if (restorePersistedValue)
        {
            if (defaultValue == null)
            {
                time = GetPersistedString("00:00");
            }
            else
            {
                time = GetPersistedString(defaultValue.ToString());
            }
        }
        else
        {
            time = defaultValue.ToString();
        }

        lastHour = GetHour(time);
        lastMinute = GetMinute(time);
    }
}

DialogPreference doesn't exist in the support libraries, and what seems to be instead is either PreferenceDialogFragment or PreferenceDialogFragmentCompat, both of which work differently, and the above code doesn't work with them.

I'm really at loss in all of this and would be glad for some help.

Thanks!

amitairos
  • 2,907
  • 11
  • 50
  • 84

2 Answers2

0

The support library is :

The Android Support Library offers a number of features that are not built into the framework. These libraries offer backward-compatible versions of new features, provide useful UI elements that are not included in the framework, and provide a range of utilities that apps can draw on https://developer.android.com/topic/libraries/support-library/index.html#overview

If you use support library you have to added to your project but if you use DialogPreference that exist in API level 1 your app will run in every android devices.

you don't need to use support library unless there is a need for some feature that is not available in your target sdk.

witch support I have to use ? deppend on witch feature and min sdk you need :

v4 Support Library

This library is designed to be used with Android 1.6 (API level 4) and higher. It includes the largest set of APIs compared to the other libraries, including support for application components, user interface features, accessibility, data handling, network connectivity, and programming utilities.

v7 Libraries

There are several libraries designed to be used with Android 2.1 (API level 7) and higher. These libraries provide specific feature sets and can be included in your application independently from each other.

v7 appcompat library

This library adds support for the Action Bar user interface design pattern.

Note: This library depends on the v4 Support Library. If you are using Ant or Eclipse, make sure you include the v4 Support Library as part of this library's classpath.

v13 Support Library

This library is designed to be used for Android 3.2 (API level 13) and higher. It adds support for the Fragment user interface pattern with the (FragmentCompat) class and additional fragment support classes

https://developer.android.com/topic/libraries/support-library/features.html

mehd azizi
  • 594
  • 1
  • 5
  • 16
  • So I shouldn't use PreferenceFragment from the Support Libraries? It will work on older devices? If so, why did Google create it? – amitairos Aug 14 '16 at 18:32
  • this components are just extra .you can use it but increases your apk size. – mehd azizi Aug 15 '16 at 05:26
  • The Support Libraries I need anyway, because some features are available only there. Which shouldn't I use, and which Preferences should I use? Which work on older apis? – amitairos Aug 15 '16 at 05:29
  • updated the answer .if you need to run your apk in sdk below version 4 use support v4 and so on . read the link https://developer.android.com/topic/libraries/support-library/features.html – mehd azizi Aug 15 '16 at 06:05
  • Thanks. Specifically for Preferences, I'm confused about all the versions. If I want to make a Time Preference Dialog that would work say on 4.2+, which version should I use? – amitairos Aug 15 '16 at 06:26
  • you can use support v7 . – mehd azizi Aug 15 '16 at 06:31
  • And how do I write it? Can I use DialogPreference along with PreferenceFragment? It doesn't work for me. – amitairos Aug 15 '16 at 06:32
0

You need a couple of things to achieve this with the support library:

A layout for the timepicker:

<!-- Layout for the TimePreference Dialog -->
<TimePicker
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/time_picker"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="18dp"
    android:paddingTop="18dp" />

The preference class which reads/writes the time preference:

import android.support.v7.preference.DialogPreference;

public class TimePreference extends DialogPreference {

    private String time;

    public TimePreference(Context context) {
        // Delegate to other constructor
        this(context, null);
    }

    public TimePreference(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.preferenceStyle);
    }

    public TimePreference(Context context, AttributeSet attrs, int defStyleAttr) {
        // Delegate to other constructor
        this(context, attrs, defStyleAttr, defStyleAttr);
    }

    public TimePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        setPositiveButtonText(R.string.set_value);
        setNegativeButtonText(R.string.cancel);
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;

        // save to SharedPreference
        persistString(time);
    }

    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        return a.getString(index);
    }

    @Override
    public int getDialogLayoutResource() {
        return R.layout.pref_dialog_time;
    }

    @Override
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
        setTime(restorePersistedValue ?
                getPersistedString(time) : (String) defaultValue);
    }

    public static int getHour(String time) {
        String[] pieces = time.split(":");

        return Integer.parseInt(pieces[0]);
    }

    public static int getMinute(String time) {
        String[] pieces = time.split(":");

        return Integer.parseInt(pieces[1]);
    }
}

a dialogFragment which controls the display of you timepicker:

public class TimePreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {

    private TimePicker mTimePicker;


    public static TimePreferenceDialogFragmentCompat newInstance(String key) {
        final TimePreferenceDialogFragmentCompat
                fragment = new TimePreferenceDialogFragmentCompat();
        final Bundle b = new Bundle(1);
        b.putString(ARG_KEY, key);
        fragment.setArguments(b);

        return fragment;
    }

    @Override
    protected void onBindDialogView(View view) {
        super.onBindDialogView(view);

        mTimePicker = view.findViewById(R.id.time_picker);

        if (mTimePicker == null) {
            throw new IllegalStateException("Dialog view must contain a TimePicker with id 'time_picker'");
        }

        String time = null;
        DialogPreference preference = getPreference();
        if (preference instanceof TimePreference) {
            time = ((TimePreference) preference).getTime();
        }

        // Set the time to the TimePicker
        if (time != null) {
            mTimePicker.setIs24HourView(DateFormat.is24HourFormat(getContext()));
            mTimePicker.setCurrentHour(TimePreference.getHour(time));
            mTimePicker.setCurrentMinute(TimePreference.getMinute(time));
        }
    }

    @Override
    public void onDialogClosed(boolean positiveResult) {
        if (positiveResult) {
            // Get the current values from the TimePicker
            int hour = mTimePicker.getCurrentHour();
            int minute = mTimePicker.getCurrentMinute();

            // Generate value to save
            String time = hour + ":" + minute;

            DialogPreference preference = getPreference();
            if (preference instanceof TimePreference) {
                TimePreference timePreference = ((TimePreference) preference);
                if (timePreference.callChangeListener(time)) {
                    timePreference.setTime(time);
                }
            }
        }
    }
}

and finally you need a custom PreferenceFragmentCompat:

public class MyPreferenceFragment extends PreferenceFragmentCompat {

    @Override
    public void onDisplayPreferenceDialog(Preference preference) {
        DialogFragment dialogFragment = null;
        if (preference instanceof TimePreference) {
            dialogFragment = TimePreferenceDialogFragmentCompat.newInstance(preference.getKey());
        }


        if (dialogFragment != null) {
            dialogFragment.setTargetFragment(this, 0);
            dialogFragment.show(this.getFragmentManager(), "android.support.v7.preference" +
                    ".PreferenceFragment.DIALOG");
        } else {
            super.onDisplayPreferenceDialog(preference);
        }
    }
}

seems to be a lot easier without the support library :-/

D-rk
  • 5,513
  • 1
  • 37
  • 55