1/*
2 * Copyright (C) 2007 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
17package com.example.android.apis.preference;
18
19import com.example.android.apis.R;
20
21import android.content.Context;
22import android.content.res.TypedArray;
23import android.os.Parcel;
24import android.os.Parcelable;
25import android.preference.Preference;
26import android.util.AttributeSet;
27import android.view.View;
28import android.widget.TextView;
29
30/**
31 * This is an example of a custom preference type. The preference counts the
32 * number of clicks it has received and stores/retrieves it from the storage.
33 */
34public class MyPreference extends Preference {
35    private int mClickCounter;
36
37    // This is the constructor called by the inflater
38    public MyPreference(Context context, AttributeSet attrs) {
39        super(context, attrs);
40
41        setWidgetLayoutResource(R.layout.preference_widget_mypreference);
42    }
43
44    @Override
45    protected void onBindView(View view) {
46        super.onBindView(view);
47
48        // Set our custom views inside the layout
49        final TextView myTextView = (TextView) view.findViewById(R.id.mypreference_widget);
50        if (myTextView != null) {
51            myTextView.setText(String.valueOf(mClickCounter));
52        }
53    }
54
55    @Override
56    protected void onClick() {
57        int newValue = mClickCounter + 1;
58        // Give the client a chance to ignore this change if they deem it
59        // invalid
60        if (!callChangeListener(newValue)) {
61            // They don't want the value to be set
62            return;
63        }
64
65        // Increment counter
66        mClickCounter = newValue;
67
68        // Save to persistent storage (this method will make sure this
69        // preference should be persistent, along with other useful checks)
70        persistInt(mClickCounter);
71
72        // Data has changed, notify so UI can be refreshed!
73        notifyChanged();
74    }
75
76    @Override
77    protected Object onGetDefaultValue(TypedArray a, int index) {
78        // This preference type's value type is Integer, so we read the default
79        // value from the attributes as an Integer.
80        return a.getInteger(index, 0);
81    }
82
83    @Override
84    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
85        if (restoreValue) {
86            // Restore state
87            mClickCounter = getPersistedInt(mClickCounter);
88        } else {
89            // Set state
90            int value = (Integer) defaultValue;
91            mClickCounter = value;
92            persistInt(value);
93        }
94    }
95
96    @Override
97    protected Parcelable onSaveInstanceState() {
98        /*
99         * Suppose a client uses this preference type without persisting. We
100         * must save the instance state so it is able to, for example, survive
101         * orientation changes.
102         */
103
104        final Parcelable superState = super.onSaveInstanceState();
105        if (isPersistent()) {
106            // No need to save instance state since it's persistent
107            return superState;
108        }
109
110        // Save the instance state
111        final SavedState myState = new SavedState(superState);
112        myState.clickCounter = mClickCounter;
113        return myState;
114    }
115
116    @Override
117    protected void onRestoreInstanceState(Parcelable state) {
118        if (!state.getClass().equals(SavedState.class)) {
119            // Didn't save state for us in onSaveInstanceState
120            super.onRestoreInstanceState(state);
121            return;
122        }
123
124        // Restore the instance state
125        SavedState myState = (SavedState) state;
126        super.onRestoreInstanceState(myState.getSuperState());
127        mClickCounter = myState.clickCounter;
128        notifyChanged();
129    }
130
131    /**
132     * SavedState, a subclass of {@link BaseSavedState}, will store the state
133     * of MyPreference, a subclass of Preference.
134     * <p>
135     * It is important to always call through to super methods.
136     */
137    private static class SavedState extends BaseSavedState {
138        int clickCounter;
139
140        public SavedState(Parcel source) {
141            super(source);
142
143            // Restore the click counter
144            clickCounter = source.readInt();
145        }
146
147        @Override
148        public void writeToParcel(Parcel dest, int flags) {
149            super.writeToParcel(dest, flags);
150
151            // Save the click counter
152            dest.writeInt(clickCounter);
153        }
154
155        public SavedState(Parcelable superState) {
156            super(superState);
157        }
158
159        public static final Parcelable.Creator<SavedState> CREATOR =
160                new Parcelable.Creator<SavedState>() {
161            public SavedState createFromParcel(Parcel in) {
162                return new SavedState(in);
163            }
164
165            public SavedState[] newArray(int size) {
166                return new SavedState[size];
167            }
168        };
169    }
170
171}
172