Skip to content

Commit 5c78693

Browse files
0xD34Djl90
authored andcommitted
Add CustomSeekBarPreference
Fix a couple of "oops". Change-Id: I374ceb023a418f72778539d1c227ee987b3978a1
1 parent 6b8fd04 commit 5c78693

File tree

5 files changed

+311
-41
lines changed

5 files changed

+311
-41
lines changed
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Copyright (C) 2014-2016 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+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:layout_width="match_parent"
19+
android:layout_height="wrap_content"
20+
android:minHeight="?android:attr/listPreferredItemHeight"
21+
android:gravity="center_vertical"
22+
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
23+
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
24+
android:clickable="false" >
25+
26+
<LinearLayout
27+
android:layout_width="match_parent"
28+
android:layout_height="wrap_content"
29+
android:orientation="vertical"
30+
android:layout_marginTop="8dip"
31+
android:layout_marginBottom="8dip">
32+
33+
<LinearLayout
34+
android:layout_width="match_parent"
35+
android:layout_height="wrap_content">
36+
<TextView android:id="@android:id/title"
37+
android:layout_width="wrap_content"
38+
android:layout_height="wrap_content"
39+
android:layout_weight="1"
40+
android:singleLine="true"
41+
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
42+
android:textColor="?android:attr/textColorPrimary"
43+
android:ellipsize="marquee"
44+
android:fadingEdge="horizontal" />
45+
<!-- Preference should place its actual preference widget here. -->
46+
<LinearLayout android:id="@android:id/widget_frame"
47+
android:layout_width="wrap_content"
48+
android:layout_height="match_parent"
49+
android:gravity="end|center_vertical"
50+
android:paddingStart="16dp"
51+
android:orientation="vertical" />
52+
</LinearLayout>
53+
54+
<RelativeLayout
55+
android:layout_width="match_parent"
56+
android:layout_height="wrap_content"
57+
android:layout_marginTop="6dp">
58+
59+
<TextView android:id="@+id/seekBarPrefValue"
60+
android:layout_width="wrap_content"
61+
android:layout_height="wrap_content"
62+
android:layout_centerInParent="true"
63+
android:layout_alignParentRight="true"
64+
android:textAppearance="@android:style/TextAppearance.Material.Body1"
65+
android:textColor="?android:attr/textColorSecondary" />
66+
67+
<LinearLayout android:id="@+id/seekBarPrefBarContainer"
68+
android:layout_centerInParent="true"
69+
android:layout_width="fill_parent"
70+
android:layout_height="wrap_content"
71+
android:layout_toLeftOf="@id/seekBarPrefValue" />
72+
</RelativeLayout>
73+
74+
</LinearLayout>
75+
76+
</FrameLayout>

res/values/statusbar_settings.xml

-39
This file was deleted.

res/values/unholy_attrs.xml

+7
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,11 @@
2626
<attr name="alphaSliderVisible" format="boolean" />
2727
</declare-styleable>
2828

29+
<!-- Base attributes available to CustomSeekBarPreference. -->
30+
<declare-styleable name="CustomSeekBarPreference">
31+
<attr name="interval" format="integer" />
32+
<attr name="min" format="integer" />
33+
<attr name="max" format="integer" />
34+
<attr name="units" format="string|reference" />
35+
</declare-styleable>
2936
</resources>

res/xml/statusbar_settings.xml

+8-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,16 @@
2222
android:title="@string/clock_settings_title"
2323
android:summary="@string/clock_settings_summary" />
2424

25+
<PreferenceScreen
26+
android:key="status_bar_battery_style"
27+
android:title="@string/status_bar_battery_style_category"
28+
android:fragment="com.unholy.settings.fragments.StatusbarBatteryStyle" />
29+
2530
<PreferenceScreen
2631
android:key="systemui_tuner_statusbar"
27-
android:title="@string/statusbar_items_category"
28-
<intent android:action="android.intent.action.MAIN"
32+
android:title="@string/statusbar_items_category">
33+
<intent
34+
android:action="android.intent.action.MAIN"
2935
android:targetPackage="com.android.systemui"
3036
android:targetClass="com.android.systemui.tuner.TunerActivity" />
3137
</PreferenceScreen>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*
2+
* Copyright (C) 2016 The Dirty Unicorns 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 com.unholy.settings.preference;
18+
19+
import android.content.Context;
20+
import android.content.res.TypedArray;
21+
import android.util.AttributeSet;
22+
import android.util.Log;
23+
import android.view.ViewParent;
24+
import android.view.ViewGroup;
25+
import android.widget.SeekBar;
26+
import android.widget.TextView;
27+
import android.support.v7.preference.*;
28+
29+
import com.android.settings.R;
30+
31+
public class CustomSeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener {
32+
private final String TAG = getClass().getName();
33+
private static final String SETTINGS_NS = "http://schemas.android.com/apk/res/com.android.settings";
34+
private static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
35+
private static final int DEFAULT_VALUE = 50;
36+
37+
private int mMin = 0;
38+
private int mInterval = 1;
39+
private int mCurrentValue;
40+
private int mDefaultValue = -1;
41+
private int mMax = 100;
42+
private String mUnits = "";
43+
private SeekBar mSeekBar;
44+
private TextView mTitle;
45+
private TextView mStatusText;
46+
47+
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
48+
int defStyleRes) {
49+
super(context, attrs, defStyleAttr, defStyleRes);
50+
final TypedArray a = context.obtainStyledAttributes(
51+
attrs, R.styleable.CustomSeekBarPreference);
52+
53+
mMax = attrs.getAttributeIntValue(SETTINGS_NS, "max", 100);
54+
mMin = attrs.getAttributeIntValue(SETTINGS_NS, "min", 0);
55+
mDefaultValue = attrs.getAttributeIntValue(ANDROIDNS, "defaultValue", -1);
56+
mUnits = getAttributeStringValue(attrs, SETTINGS_NS, "units", "");
57+
58+
Integer id = a.getResourceId(R.styleable.CustomSeekBarPreference_units, 0);
59+
if (id > 0) {
60+
mUnits = context.getResources().getString(id);
61+
}
62+
63+
try {
64+
String newInterval = attrs.getAttributeValue(SETTINGS_NS, "interval");
65+
if (newInterval != null)
66+
mInterval = Integer.parseInt(newInterval);
67+
} catch (Exception e) {
68+
Log.e(TAG, "Invalid interval value", e);
69+
}
70+
71+
a.recycle();
72+
mSeekBar = new SeekBar(context, attrs);
73+
mSeekBar.setMax(mMax - mMin);
74+
mSeekBar.setOnSeekBarChangeListener(this);
75+
setLayoutResource(R.layout.preference_custom_seekbar);
76+
}
77+
78+
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
79+
this(context, attrs, defStyleAttr, 0);
80+
}
81+
82+
public CustomSeekBarPreference(Context context, AttributeSet attrs) {
83+
this(context, attrs, 0);
84+
}
85+
86+
public CustomSeekBarPreference(Context context) {
87+
this(context, null);
88+
}
89+
90+
private String getAttributeStringValue(AttributeSet attrs, String namespace, String name,
91+
String defaultValue) {
92+
String value = attrs.getAttributeValue(namespace, name);
93+
if (value == null)
94+
value = defaultValue;
95+
96+
return value;
97+
}
98+
99+
@Override
100+
public void onDependencyChanged(Preference dependency, boolean disableDependent) {
101+
super.onDependencyChanged(dependency, disableDependent);
102+
this.setShouldDisableView(true);
103+
if (mTitle != null)
104+
mTitle.setEnabled(!disableDependent);
105+
if (mSeekBar != null)
106+
mSeekBar.setEnabled(!disableDependent);
107+
if (mStatusText != null)
108+
mStatusText.setEnabled(!disableDependent);
109+
}
110+
111+
@Override
112+
public void onBindViewHolder(PreferenceViewHolder view) {
113+
super.onBindViewHolder(view);
114+
try
115+
{
116+
// move our seekbar to the new view we've been given
117+
ViewParent oldContainer = mSeekBar.getParent();
118+
ViewGroup newContainer = (ViewGroup) view.findViewById(R.id.seekBarPrefBarContainer);
119+
120+
if (oldContainer != newContainer) {
121+
// remove the seekbar from the old view
122+
if (oldContainer != null) {
123+
((ViewGroup) oldContainer).removeView(mSeekBar);
124+
}
125+
// remove the existing seekbar (there may not be one) and add ours
126+
newContainer.removeAllViews();
127+
newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT,
128+
ViewGroup.LayoutParams.WRAP_CONTENT);
129+
}
130+
} catch (Exception ex) {
131+
Log.e(TAG, "Error binding view: " + ex.toString());
132+
}
133+
mStatusText = (TextView) view.findViewById(R.id.seekBarPrefValue);
134+
mStatusText.setText(String.valueOf(mCurrentValue) + mUnits);
135+
mStatusText.setMinimumWidth(30);
136+
mSeekBar.setProgress(mCurrentValue - mMin);
137+
mTitle = (TextView) view.findViewById(android.R.id.title);
138+
}
139+
140+
public void setMax(int max) {
141+
mMax = max;
142+
}
143+
144+
public void setMin(int min) {
145+
mMin = min;
146+
}
147+
148+
public void setIntervalValue(int value) {
149+
mInterval = value;
150+
}
151+
152+
public void setValue(int value) {
153+
mCurrentValue = value;
154+
}
155+
156+
@Override
157+
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
158+
int newValue = progress + mMin;
159+
if (newValue > mMax)
160+
newValue = mMax;
161+
else if (newValue < mMin)
162+
newValue = mMin;
163+
else if (mInterval != 1 && newValue % mInterval != 0)
164+
newValue = Math.round(((float) newValue) / mInterval) * mInterval;
165+
166+
// change rejected, revert to the previous value
167+
if (!callChangeListener(newValue)) {
168+
seekBar.setProgress(mCurrentValue - mMin);
169+
return;
170+
}
171+
// change accepted, store it
172+
mCurrentValue = newValue;
173+
if (mStatusText != null) {
174+
mStatusText.setText(String.valueOf(newValue) + mUnits);
175+
}
176+
persistInt(newValue);
177+
}
178+
179+
@Override
180+
public void onStartTrackingTouch(SeekBar seekBar) {
181+
}
182+
183+
@Override
184+
public void onStopTrackingTouch(SeekBar seekBar) {
185+
notifyChanged();
186+
}
187+
188+
@Override
189+
protected Object onGetDefaultValue(TypedArray ta, int index) {
190+
int defaultValue = ta.getInt(index, DEFAULT_VALUE);
191+
return defaultValue;
192+
}
193+
194+
@Override
195+
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
196+
if (restoreValue) {
197+
mCurrentValue = getPersistedInt(mCurrentValue);
198+
}
199+
else {
200+
int temp = 0;
201+
try {
202+
temp = (Integer) defaultValue;
203+
} catch (Exception ex) {
204+
Log.e(TAG, "Invalid default value: " + defaultValue.toString());
205+
}
206+
persistInt(temp);
207+
mCurrentValue = temp;
208+
}
209+
}
210+
211+
@Override
212+
public void setEnabled(boolean enabled) {
213+
if (mSeekBar != null && mStatusText != null && mTitle != null) {
214+
mSeekBar.setEnabled(enabled);
215+
mStatusText.setEnabled(enabled);
216+
mTitle.setEnabled(enabled);
217+
}
218+
super.setEnabled(enabled);
219+
}
220+
}

0 commit comments

Comments
 (0)