Add CustomSeekBarPreference

Change-Id: I374ceb023a418f72778539d1c227ee987b3978a1

Signed-off-by: xyyx <xyyx@mail.ru>
This commit is contained in:
d34d
2016-09-18 08:20:55 -07:00
committed by hungphan2001
parent dd31238803
commit 88870041dc
3 changed files with 320 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014-2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:clickable="false" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
android:textColor="?android:attr/textColorPrimary"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<!-- Preference should place its actual preference widget here. -->
<LinearLayout android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="end|center_vertical"
android:paddingStart="16dp"
android:orientation="vertical" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp">
<TextView android:id="@+id/seekBarPrefValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_alignParentRight="true"
android:textAppearance="@android:style/TextAppearance.Material.Body1"
android:textColor="?android:attr/textColorSecondary" />
<LinearLayout android:id="@+id/seekBarPrefBarContainer"
android:layout_centerInParent="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/seekBarPrefValue" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Pure Nexus Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Base attributes available to CustomSeekBarPreference. -->
<declare-styleable name="CustomSeekBarPreference">
<attr name="interval" format="integer" />
<attr name="min" format="integer" />
<attr name="max" format="integer" />
<attr name="units" format="string|reference" />
</declare-styleable>
</resources>

View File

@@ -0,0 +1,220 @@
/*
* Copyright (C) 2016 The Dirty Unicorns Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.cherish.settings.preferences;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewParent;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import android.support.v7.preference.*;
import com.android.settings.R;
public class CustomSeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener {
private final String TAG = getClass().getName();
private static final String SETTINGS_NS = "http://schemas.android.com/apk/res/com.android.settings";
private static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
private static final int DEFAULT_VALUE = 50;
private int mMin = 0;
private int mInterval = 1;
private int mCurrentValue;
private int mDefaultValue = -1;
private int mMax = 100;
private String mUnits = "";
private SeekBar mSeekBar;
private TextView mTitle;
private TextView mStatusText;
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.CustomSeekBarPreference);
mMax = attrs.getAttributeIntValue(SETTINGS_NS, "max", 100);
mMin = attrs.getAttributeIntValue(SETTINGS_NS, "min", 0);
mDefaultValue = attrs.getAttributeIntValue(ANDROIDNS, "defaultValue", -1);
mUnits = getAttributeStringValue(attrs, SETTINGS_NS, "units", "");
Integer id = a.getResourceId(R.styleable.CustomSeekBarPreference_units, 0);
if (id > 0) {
mUnits = context.getResources().getString(id);
}
try {
String newInterval = attrs.getAttributeValue(SETTINGS_NS, "interval");
if (newInterval != null)
mInterval = Integer.parseInt(newInterval);
} catch (Exception e) {
Log.e(TAG, "Invalid interval value", e);
}
a.recycle();
mSeekBar = new SeekBar(context, attrs);
mSeekBar.setMax(mMax - mMin);
mSeekBar.setOnSeekBarChangeListener(this);
setLayoutResource(R.layout.preference_cherish_seekbar);
}
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public CustomSeekBarPreference(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomSeekBarPreference(Context context) {
this(context, null);
}
private String getAttributeStringValue(AttributeSet attrs, String namespace, String name,
String defaultValue) {
String value = attrs.getAttributeValue(namespace, name);
if (value == null)
value = defaultValue;
return value;
}
@Override
public void onDependencyChanged(Preference dependency, boolean disableDependent) {
super.onDependencyChanged(dependency, disableDependent);
this.setShouldDisableView(true);
if (mTitle != null)
mTitle.setEnabled(!disableDependent);
if (mSeekBar != null)
mSeekBar.setEnabled(!disableDependent);
if (mStatusText != null)
mStatusText.setEnabled(!disableDependent);
}
@Override
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);
try
{
// move our seekbar to the new view we've been given
ViewParent oldContainer = mSeekBar.getParent();
ViewGroup newContainer = (ViewGroup) view.findViewById(R.id.seekBarPrefBarContainer);
if (oldContainer != newContainer) {
// remove the seekbar from the old view
if (oldContainer != null) {
((ViewGroup) oldContainer).removeView(mSeekBar);
}
// remove the existing seekbar (there may not be one) and add ours
newContainer.removeAllViews();
newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
} catch (Exception ex) {
Log.e(TAG, "Error binding view: " + ex.toString());
}
mStatusText = (TextView) view.findViewById(R.id.seekBarPrefValue);
mStatusText.setText(String.valueOf(mCurrentValue) + mUnits);
mStatusText.setMinimumWidth(30);
mSeekBar.setProgress(mCurrentValue - mMin);
mTitle = (TextView) view.findViewById(android.R.id.title);
}
public void setMax(int max) {
mMax = max;
}
public void setMin(int min) {
mMin = min;
}
public void setIntervalValue(int value) {
mInterval = value;
}
public void setValue(int value) {
mCurrentValue = value;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int newValue = progress + mMin;
if (newValue > mMax)
newValue = mMax;
else if (newValue < mMin)
newValue = mMin;
else if (mInterval != 1 && newValue % mInterval != 0)
newValue = Math.round(((float) newValue) / mInterval) * mInterval;
// change rejected, revert to the previous value
if (!callChangeListener(newValue)) {
seekBar.setProgress(mCurrentValue - mMin);
return;
}
// change accepted, store it
mCurrentValue = newValue;
if (mStatusText != null) {
mStatusText.setText(String.valueOf(newValue) + mUnits);
}
persistInt(newValue);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
notifyChanged();
}
@Override
protected Object onGetDefaultValue(TypedArray ta, int index) {
int defaultValue = ta.getInt(index, DEFAULT_VALUE);
return defaultValue;
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
if (restoreValue) {
mCurrentValue = getPersistedInt(mCurrentValue);
}
else {
int temp = 0;
try {
temp = (Integer) defaultValue;
} catch (Exception ex) {
Log.e(TAG, "Invalid default value: " + defaultValue.toString());
}
persistInt(temp);
mCurrentValue = temp;
}
}
@Override
public void setEnabled(boolean enabled) {
if (mSeekBar != null && mStatusText != null && mTitle != null) {
mSeekBar.setEnabled(enabled);
mStatusText.setEnabled(enabled);
mTitle.setEnabled(enabled);
}
super.setEnabled(enabled);
}
}