/* * Copyright 2012 Jay Weisskopf * * Licensed under the MIT License (see LICENSE.txt) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies * or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Source: https://github.com/jayschwa/AndroidSliderPreference */ package com.fsck.k9.activity.setup; import android.content.Context; import android.content.res.TypedArray; import android.os.Bundle; import android.os.Parcelable; import android.preference.DialogPreference; import android.support.annotation.ArrayRes; import android.support.annotation.StringRes; import android.util.AttributeSet; import android.view.View; import android.widget.SeekBar; import com.fsck.k9.*; /** * @author Jay Weisskopf */ public class SliderPreference extends DialogPreference { private static final String STATE_KEY_SUPER = "super"; private static final String STATE_KEY_SEEK_BAR_VALUE = "seek_bar_value"; protected final static int SEEKBAR_RESOLUTION = 10000; protected float mValue; protected int mSeekBarValue; protected CharSequence[] mSummaries; /** * @param context * @param attrs */ public SliderPreference(Context context, AttributeSet attrs) { super(context, attrs); setup(context, attrs); } /** * @param context * @param attrs * @param defStyle */ public SliderPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setup(context, attrs); } private void setup(Context context, AttributeSet attrs) { setDialogLayoutResource(R.layout.slider_preference_dialog); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SliderPreference); try { setSummary(a.getTextArray(R.styleable.SliderPreference_android_summary)); } catch (Exception e) { // Do nothing } a.recycle(); } @Override protected Object onGetDefaultValue(TypedArray a, int index) { return a.getFloat(index, 0); } @Override protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { setValue(restoreValue ? getPersistedFloat(mValue) : (Float) defaultValue); } @Override public CharSequence getSummary() { if (mSummaries != null && mSummaries.length > 0) { int index = (int) (mValue * mSummaries.length); index = Math.min(index, mSummaries.length - 1); return mSummaries[index]; } else { return super.getSummary(); } } public void setSummary(CharSequence[] summaries) { mSummaries = summaries; } @Override public void setSummary(CharSequence summary) { super.setSummary(summary); mSummaries = null; } @Override public void setSummary(@ArrayRes int summaryResId) { try { setSummary(getContext().getResources().getStringArray(summaryResId)); } catch (Exception e) { super.setSummary(summaryResId); } } public float getValue() { return mValue; } public void setValue(float value) { value = Math.max(0, Math.min(value, 1)); // clamp to [0, 1] if (shouldPersist()) { persistFloat(value); } if (value != mValue) { mValue = value; notifyChanged(); } } @Override protected View onCreateDialogView() { mSeekBarValue = (int) (mValue * SEEKBAR_RESOLUTION); View view = super.onCreateDialogView(); SeekBar seekbar = (SeekBar) view.findViewById(R.id.slider_preference_seekbar); seekbar.setMax(SEEKBAR_RESOLUTION); seekbar.setProgress(mSeekBarValue); seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { SliderPreference.this.mSeekBarValue = progress; callChangeListener((float) SliderPreference.this.mSeekBarValue / SEEKBAR_RESOLUTION); } } }); return view; } @Override protected void onDialogClosed(boolean positiveResult) { final float newValue = (float) mSeekBarValue / SEEKBAR_RESOLUTION; if (positiveResult && callChangeListener(newValue)) { setValue(newValue); } else { callChangeListener(mValue); } super.onDialogClosed(positiveResult); } @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); Bundle state = new Bundle(); state.putParcelable(STATE_KEY_SUPER, superState); state.putInt(STATE_KEY_SEEK_BAR_VALUE, mSeekBarValue); return state; } @Override protected void onRestoreInstanceState(Parcelable state) { Bundle bundle = (Bundle) state; super.onRestoreInstanceState(bundle.getParcelable(STATE_KEY_SUPER)); mSeekBarValue = bundle.getInt(STATE_KEY_SEEK_BAR_VALUE); callChangeListener((float) mSeekBarValue / SEEKBAR_RESOLUTION); } }