Home | History | Annotate | Download | only in preference
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.preference;
     18 
     19 import android.content.Context;
     20 import android.content.res.TypedArray;
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 import android.util.AttributeSet;
     24 import android.view.KeyEvent;
     25 import android.view.View;
     26 import android.widget.SeekBar;
     27 import android.widget.SeekBar.OnSeekBarChangeListener;
     28 
     29 /**
     30  * @hide
     31  */
     32 public class SeekBarPreference extends Preference
     33         implements OnSeekBarChangeListener {
     34 
     35     private int mProgress;
     36     private int mMax;
     37     private boolean mTrackingTouch;
     38 
     39     public SeekBarPreference(
     40             Context context, AttributeSet attrs, int defStyle) {
     41         super(context, attrs, defStyle);
     42         TypedArray a = context.obtainStyledAttributes(attrs,
     43                 com.android.internal.R.styleable.ProgressBar, defStyle, 0);
     44         setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax));
     45         a.recycle();
     46         setLayoutResource(com.android.internal.R.layout.preference_widget_seekbar);
     47     }
     48 
     49     public SeekBarPreference(Context context, AttributeSet attrs) {
     50         this(context, attrs, 0);
     51     }
     52 
     53     public SeekBarPreference(Context context) {
     54         this(context, null);
     55     }
     56 
     57     @Override
     58     protected void onBindView(View view) {
     59         super.onBindView(view);
     60         SeekBar seekBar = (SeekBar) view.findViewById(
     61                 com.android.internal.R.id.seekbar);
     62         seekBar.setOnSeekBarChangeListener(this);
     63         seekBar.setMax(mMax);
     64         seekBar.setProgress(mProgress);
     65         seekBar.setEnabled(isEnabled());
     66     }
     67 
     68     @Override
     69     public CharSequence getSummary() {
     70         return null;
     71     }
     72 
     73     @Override
     74     protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
     75         setProgress(restoreValue ? getPersistedInt(mProgress)
     76                 : (Integer) defaultValue);
     77     }
     78 
     79     @Override
     80     protected Object onGetDefaultValue(TypedArray a, int index) {
     81         return a.getInt(index, 0);
     82     }
     83 
     84     @Override
     85     public boolean onKey(View v, int keyCode, KeyEvent event) {
     86         if (event.getAction() != KeyEvent.ACTION_UP) {
     87             if (keyCode == KeyEvent.KEYCODE_PLUS
     88                     || keyCode == KeyEvent.KEYCODE_EQUALS) {
     89                 setProgress(getProgress() + 1);
     90                 return true;
     91             }
     92             if (keyCode == KeyEvent.KEYCODE_MINUS) {
     93                 setProgress(getProgress() - 1);
     94                 return true;
     95             }
     96         }
     97         return false;
     98     }
     99 
    100     public void setMax(int max) {
    101         if (max != mMax) {
    102             mMax = max;
    103             notifyChanged();
    104         }
    105     }
    106 
    107     public void setProgress(int progress) {
    108         setProgress(progress, true);
    109     }
    110 
    111     private void setProgress(int progress, boolean notifyChanged) {
    112         if (progress > mMax) {
    113             progress = mMax;
    114         }
    115         if (progress < 0) {
    116             progress = 0;
    117         }
    118         if (progress != mProgress) {
    119             mProgress = progress;
    120             persistInt(progress);
    121             if (notifyChanged) {
    122                 notifyChanged();
    123             }
    124         }
    125     }
    126 
    127     public int getProgress() {
    128         return mProgress;
    129     }
    130 
    131     /**
    132      * Persist the seekBar's progress value if callChangeListener
    133      * returns true, otherwise set the seekBar's progress to the stored value
    134      */
    135     void syncProgress(SeekBar seekBar) {
    136         int progress = seekBar.getProgress();
    137         if (progress != mProgress) {
    138             if (callChangeListener(progress)) {
    139                 setProgress(progress, false);
    140             } else {
    141                 seekBar.setProgress(mProgress);
    142             }
    143         }
    144     }
    145 
    146     @Override
    147     public void onProgressChanged(
    148             SeekBar seekBar, int progress, boolean fromUser) {
    149         if (fromUser && !mTrackingTouch) {
    150             syncProgress(seekBar);
    151         }
    152     }
    153 
    154     @Override
    155     public void onStartTrackingTouch(SeekBar seekBar) {
    156         mTrackingTouch = true;
    157     }
    158 
    159     @Override
    160     public void onStopTrackingTouch(SeekBar seekBar) {
    161         mTrackingTouch = false;
    162         if (seekBar.getProgress() != mProgress) {
    163             syncProgress(seekBar);
    164         }
    165     }
    166 
    167     @Override
    168     protected Parcelable onSaveInstanceState() {
    169         /*
    170          * Suppose a client uses this preference type without persisting. We
    171          * must save the instance state so it is able to, for example, survive
    172          * orientation changes.
    173          */
    174 
    175         final Parcelable superState = super.onSaveInstanceState();
    176         if (isPersistent()) {
    177             // No need to save instance state since it's persistent
    178             return superState;
    179         }
    180 
    181         // Save the instance state
    182         final SavedState myState = new SavedState(superState);
    183         myState.progress = mProgress;
    184         myState.max = mMax;
    185         return myState;
    186     }
    187 
    188     @Override
    189     protected void onRestoreInstanceState(Parcelable state) {
    190         if (!state.getClass().equals(SavedState.class)) {
    191             // Didn't save state for us in onSaveInstanceState
    192             super.onRestoreInstanceState(state);
    193             return;
    194         }
    195 
    196         // Restore the instance state
    197         SavedState myState = (SavedState) state;
    198         super.onRestoreInstanceState(myState.getSuperState());
    199         mProgress = myState.progress;
    200         mMax = myState.max;
    201         notifyChanged();
    202     }
    203 
    204     /**
    205      * SavedState, a subclass of {@link BaseSavedState}, will store the state
    206      * of MyPreference, a subclass of Preference.
    207      * <p>
    208      * It is important to always call through to super methods.
    209      */
    210     private static class SavedState extends BaseSavedState {
    211         int progress;
    212         int max;
    213 
    214         public SavedState(Parcel source) {
    215             super(source);
    216 
    217             // Restore the click counter
    218             progress = source.readInt();
    219             max = source.readInt();
    220         }
    221 
    222         @Override
    223         public void writeToParcel(Parcel dest, int flags) {
    224             super.writeToParcel(dest, flags);
    225 
    226             // Save the click counter
    227             dest.writeInt(progress);
    228             dest.writeInt(max);
    229         }
    230 
    231         public SavedState(Parcelable superState) {
    232             super(superState);
    233         }
    234 
    235         @SuppressWarnings("unused")
    236         public static final Parcelable.Creator<SavedState> CREATOR =
    237                 new Parcelable.Creator<SavedState>() {
    238             public SavedState createFromParcel(Parcel in) {
    239                 return new SavedState(in);
    240             }
    241 
    242             public SavedState[] newArray(int size) {
    243                 return new SavedState[size];
    244             }
    245         };
    246     }
    247 }
    248