Add seekbar and list settings preferences

Taken from AICP
This commit is contained in:
SpiritCroc
2018-03-25 19:50:45 -07:00
committed by unknown
parent cd35b45d96
commit baff4b6ed0
18 changed files with 1142 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M0 0h24v24H0z" />
<path
android:fillColor="?android:attr/textColorSecondary"
android:pathData="M12.5 8c-2.65 0-5.05 .99 -6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88
5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z" />
</vector>

View File

@@ -0,0 +1,24 @@
<!--
Copyright (C) 2016 AICP
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?android:attr/colorControlNormal"
android:pathData="M19,13H5V11H19V13Z" />
</vector>

View File

@@ -0,0 +1,24 @@
<!--
Copyright (C) 2015 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
android:fillColor="?android:attr/colorControlNormal"
android:pathData="M38.0,26.0L26.0,26.0l0.0,12.0l-4.0,0.0L22.0,26.0L10.0,26.0l0.0,-4.0l12.0,0.0L22.0,10.0l4.0,0.0l0.0,12.0l12.0,0.0l0.0,4.0z"/>
</vector>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* Copyright 2017, 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.
*/
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/value_popup_view_bg" />
<corners android:radius="22dp" />
</shape>

View File

@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/activatedBackgroundIndicator"
android:clipToPadding="false">
<LinearLayout
android:id="@android:id/icon_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="-4dp"
android:minWidth="60dp"
android:gravity="start|center_vertical"
android:orientation="horizontal"
android:paddingEnd="12dp"
android:paddingTop="4dp"
android:paddingBottom="4dp">
<com.android.internal.widget.PreferenceImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="48dp"
android:maxHeight="48dp" />
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<TextView android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItem"
android:ellipsize="marquee" />
<TextView android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignStart="@android:id/title"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10"
android:ellipsize="end" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/summary" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageMinus"
android:src="@drawable/ic_seekbar_minus"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imagePlus"
android:src="@drawable/ic_seekbar_plus"
android:layout_alignParentRight="true"
android:layout_centerInParent="true" />
<TextView android:id="@+id/seekBarPrefUnitsRight"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:paddingStart="3dp"
android:layout_toLeftOf="@+id/imagePlus" />
<TextView android:id="@+id/seekBarPrefValue"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/seekBarPrefUnitsRight"
android:gravity="right"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary" />
<SeekBar android:id="@+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_toLeftOf="@+id/seekBarPrefValue"
android:layout_toRightOf="@+id/imageMinus" />
<TextView android:id="@+id/seekBarPrefUnitsLeft"
android:layout_centerInParent="true"
android:layout_toLeftOf="@id/seekBarPrefValue"
android:paddingEnd="3dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary" />
</RelativeLayout>
</RelativeLayout>
<LinearLayout android:id="@+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>

View File

@@ -0,0 +1,5 @@
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/SeekBarPreferenceChamValueView" />

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014-2017 AICP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<declare-styleable name="SeekBarPreference">
<!-- preference -->
<attr name="unitsLeft" format="string|reference" />
<attr name="unitsRight" format="string|reference" />
<attr name="interval" format="integer" />
<!-- style -->
<attr name="thumb_default_value_color" format="color" />
<attr name="value_popup_view_fg" format="color" />
<attr name="value_popup_view_bg" format="color" />
</declare-styleable>
</resources>

View File

@@ -0,0 +1,7 @@
<resources>
<!-- SeekBarPreferenceCham: offset of the value popup -->
<dimen name="seek_bar_preference_cham_value_x_offset">0dp</dimen>
<dimen name="seek_bar_preference_cham_value_y_offset">-16dp</dimen>
</resources>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/**
* Copyright (C) 2017 AICP
*
* 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="seekbar_no_default_value">No default value set</string>
<string name="seekbar_default_value_set">Value set to default of <xliff:g id="number">%d</xliff:g></string>
<string name="seekbar_default_value_already_set">Default value is already set</string>
<string name="seekbar_default_string">Default</string>
</resources>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 AICP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<style name="SeekBarPreferenceChamValueTextAppearance" parent="@*android:style/TextAppearance.Toast" />
<!-- SeekBarPreferenceCham value popup -->
<style name="SeekBarPreferenceChamValueView">
<item name="android:textColor">?attr/value_popup_view_fg</item>
<item name="android:textAppearance">@style/SeekBarPreferenceChamValueTextAppearance</item>
<item name="android:background">@drawable/seekbar_popup_bg</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:paddingVertical">15dp</item>
<item name="android:fitsSystemWindows">false</item>
</style>
</resources>

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2017-2018 AICP
*
* 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.text.TextUtils;
import android.util.AttributeSet;
public class ListPreference extends androidx.preference.ListPreference {
private boolean mAutoSummary = false;
public ListPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListPreference(Context context) {
super(context);
}
@Override
public void setValue(String value) {
super.setValue(value);
if (mAutoSummary || TextUtils.isEmpty(getSummary())) {
setSummary(getEntry(), true);
}
}
@Override
public void setSummary(CharSequence summary) {
setSummary(summary, false);
}
private void setSummary(CharSequence summary, boolean autoSummary) {
mAutoSummary = autoSummary;
super.setSummary(summary);
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (C) 2017 AICP
*
* 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.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
public class LongClickablePreference extends Preference {
private Handler mHandler = new Handler();
private boolean mAllowNormalClick;
private boolean mAllowBurst;
private int mClickableViewId = 0;
private int mLongClickDurationMillis;
private int mLongClickBurstMillis = 0;
private PreferenceViewHolder mViewHolder;
private Preference.OnPreferenceClickListener mClickListener;
private Preference.OnPreferenceClickListener mLongClickListener;
public LongClickablePreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public LongClickablePreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LongClickablePreference(Context context) {
super(context);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mViewHolder = holder;
setupClickListeners();
}
@Override
public void setOnPreferenceClickListener(
Preference.OnPreferenceClickListener onPreferenceClickListener) {
mClickListener = onPreferenceClickListener;
setupClickListeners();
}
public void setOnLongClickListener(int viewId, int longClickDurationMillis,
Preference.OnPreferenceClickListener onPreferenceClickListener) {
mClickableViewId = viewId;
mLongClickDurationMillis = longClickDurationMillis;
mLongClickListener = onPreferenceClickListener;
setupClickListeners();
}
private Runnable mLongClickRunnable = new Runnable() {
@Override
public void run() {
mAllowNormalClick = false;
mLongClickListener.onPreferenceClick(LongClickablePreference.this);
if (mAllowBurst && mLongClickBurstMillis > 0) {
mHandler.postDelayed(this, mLongClickBurstMillis);
}
}
};
public void setLongClickBurst(int intervalMillis) {
mLongClickBurstMillis = intervalMillis;
}
private void setupClickListeners() {
// We can't put long click listener on our view without sacrificing default
// preference click functionality, so detect long clicks manually with touch listener
if (mClickableViewId != 0 && mViewHolder != null) {
View view = mViewHolder.findViewById(mClickableViewId);
if (view != null) {
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mAllowNormalClick = true;
mAllowBurst = true;
mHandler.postDelayed(mLongClickRunnable,
mLongClickDurationMillis);
break;
case MotionEvent.ACTION_UP:
mHandler.removeCallbacks(mLongClickRunnable);
mAllowBurst = false;
break;
}
return false;
}
});
}
}
// Use our own preference click listener to handle both normal and long clicks
if (getOnPreferenceClickListener() == null) {
super.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
mAllowBurst = false;
mHandler.removeCallbacks(mLongClickRunnable);
if (mAllowNormalClick) {
return mClickListener != null &&
mClickListener.onPreferenceClick(preference);
} else {
// Long press done
return true;
}
}
});
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2017-2018 AICP
*
* 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.text.TextUtils;
import android.util.AttributeSet;
public class SecureSettingListPreference extends ListPreference {
public SecureSettingListPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
}
public SecureSettingListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
}
public SecureSettingListPreference(Context context) {
super(context);
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
// This is what default ListPreference implementation is doing without respecting
// real default value:
//setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
// Instead, we better do
setValue(restoreValue ? getPersistedString((String) defaultValue) : (String) defaultValue);
}
}

View File

@@ -0,0 +1,389 @@
package com.cherish.settings.preferences;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
public class SeekBarPreferenceCham extends Preference implements SeekBar.OnSeekBarChangeListener {
private final String TAG = getClass().getName();
private static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
private static final String PDXNS = "http://schemas.android.com/apk/res-auto";
private static final int DEFAULT_VALUE = 50;
private int mMaxValue = 100;
private int mMinValue = 0;
private int mInterval = 1;
private int mDefaultValue = -1;
private int mCurrentValue;
private String mUnitsLeft = "";
private String mUnitsRight = "";
private SeekBar mSeekBar;
//private TextView mTitle;
private TextView mUnitsLeftText;
private TextView mUnitsRightText;
private ImageView mImagePlus;
private ImageView mImageMinus;
private Drawable mProgressThumb;
private int mThumbDefaultValueColor;
private TextView mStatusText;
private TextView mPopupValue;
private boolean mTrackingTouch = false;
private boolean mPopupAdded = false;
private int mPopupWidth = 0;
private boolean initialised = false;
public SeekBarPreferenceCham(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.seek_bar_preference);
setValuesFromXml(attrs, context);
}
public SeekBarPreferenceCham(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setLayoutResource(R.layout.seek_bar_preference);
setValuesFromXml(attrs, context);
}
private void setValuesFromXml(AttributeSet attrs, Context context) {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.SeekBarPreference);
mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100);
mMinValue = attrs.getAttributeIntValue(ANDROIDNS, "min", 0);
mDefaultValue = attrs.getAttributeIntValue(ANDROIDNS, "defaultValue", -1);
if (mDefaultValue != attrs.getAttributeIntValue(ANDROIDNS, "defaultValue", -2)) {
mDefaultValue = (mMinValue + mMaxValue) / 2;
Log.w(TAG, "Preference with key \"" + getKey() +
"\" does not have a default value set in xml, assuming " + mDefaultValue +
" until further changes");
}
if (mDefaultValue < mMinValue || mDefaultValue > mMaxValue) {
throw new IllegalArgumentException("Default value is out of range!");
}
mUnitsLeft = getAttributeStringValue(attrs, PDXNS, "unitsLeft", "");
mUnitsRight = getAttributeStringValue(attrs, PDXNS, "unitsRight", "");
Integer idR = a.getResourceId(R.styleable.SeekBarPreference_unitsRight, 0);
if (idR > 0) {
mUnitsRight = context.getResources().getString(idR);
}
Integer idL = a.getResourceId(R.styleable.SeekBarPreference_unitsLeft, 0);
if (idL > 0) {
mUnitsLeft = context.getResources().getString(idL);
}
try {
String newInterval = attrs.getAttributeValue(PDXNS, "interval");
if(newInterval != null)
mInterval = Integer.parseInt(newInterval);
}
catch(Exception e) {
Log.e(TAG, "Invalid interval value", e);
}
mThumbDefaultValueColor = a.getColor(
R.styleable.SeekBarPreference_thumb_default_value_color, 0xff000000);
a.recycle();
}
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 (mImagePlus != null)
mImagePlus.setEnabled(!disableDependent);
if (mImageMinus != null)
mImageMinus.setEnabled(!disableDependent);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mSeekBar = (SeekBar) holder.findViewById(R.id.seekbar);
// Remove possible previously attached change listener to prevent setting wrong values
mSeekBar.setOnSeekBarChangeListener(null);
mSeekBar.setMax(mMaxValue - mMinValue);
//mTitle = (TextView) holder.findViewById(android.R.id.title);
mUnitsLeftText = (TextView) holder.findViewById(R.id.seekBarPrefUnitsLeft);
mUnitsRightText = (TextView) holder.findViewById(R.id.seekBarPrefUnitsRight);
mImagePlus = (ImageView) holder.findViewById(R.id.imagePlus);
mImagePlus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mSeekBar.setProgress((mCurrentValue + mInterval) - mMinValue);
}
});
mImagePlus.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
mSeekBar.setProgress((mCurrentValue + (mMaxValue-mMinValue)/10) - mMinValue);
return true;
}
});
mImageMinus = (ImageView) holder.findViewById(R.id.imageMinus);
mImageMinus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mSeekBar.setProgress((mCurrentValue - mInterval) - mMinValue);
}
});
mImageMinus.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
mSeekBar.setProgress((mCurrentValue - (mMaxValue-mMinValue)/10) - mMinValue);
return true;
}
});
mProgressThumb = mSeekBar.getThumb();
mStatusText = (TextView) holder.findViewById(R.id.seekBarPrefValue);
mStatusText.setMinimumWidth(30);
mStatusText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
final String defaultValue = getContext().getString(R.string.seekbar_default_value_set,
mDefaultValue);
if (mDefaultValue != -1) {
if (mDefaultValue != mCurrentValue) {
mCurrentValue = mDefaultValue;
updateView();
Toast.makeText(getContext(), defaultValue, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), R.string.seekbar_default_value_already_set,
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getContext(), R.string.seekbar_no_default_value,
Toast.LENGTH_LONG).show();
}
return true;
}
});
LayoutInflater mInflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mPopupValue = (TextView) mInflater.inflate(R.layout.seek_bar_value_popup, null, false);
mPopupValue.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int width = mPopupValue.getWidth();
if (width != mPopupWidth) {
mPopupWidth = mPopupValue.getWidth();
startUpdateViewValue();
}
}
});
initialised = true;
updateView();
mSeekBar.setOnSeekBarChangeListener(this);
}
/**
* Update a SeekBarPreferenceCham view with our current state
* @param view
*/
protected void updateView() {
if (!initialised) {
return;
}
try {
mStatusText.setText(String.valueOf(mCurrentValue));
mSeekBar.setProgress(mCurrentValue - mMinValue);
mUnitsRightText.setText(mUnitsRight);
mUnitsLeftText.setText(mUnitsLeft);
updateCurrentValueText();
}
catch(Exception e) {
Log.e(TAG, "Error updating seek bar preference", e);
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int newValue = progress + mMinValue;
if(newValue > mMaxValue)
newValue = mMaxValue;
else if(newValue < mMinValue)
newValue = mMinValue;
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 - mMinValue);
return;
}
// change accepted, store it
mCurrentValue = newValue;
updateCurrentValueText();
if (fromUser) {
startUpdateViewValue();
} else {
stopUpdateViewValue();
}
persistInt(newValue);
}
private void updateCurrentValueText() {
if (mCurrentValue == mDefaultValue && mDefaultValue != -1) {
mStatusText.setText(R.string.seekbar_default_string);
mProgressThumb.setColorFilter(mThumbDefaultValueColor, PorterDuff.Mode.SRC_IN);
mUnitsLeftText.setVisibility(View.GONE);
mUnitsRightText.setVisibility(View.GONE);
} else {
mStatusText.setText(String.valueOf(mCurrentValue));
mProgressThumb.clearColorFilter();
mUnitsLeftText.setVisibility(View.VISIBLE);
mUnitsRightText.setVisibility(View.VISIBLE);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
startUpdateViewValue();
mTrackingTouch = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
notifyChanged();
stopUpdateViewValue();
mTrackingTouch = false;
}
@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) {
int defaultVal;
if (defaultValue instanceof Integer) {
defaultVal = (Integer) defaultValue;
} else {
defaultVal = mDefaultValue;
}
setValue(restoreValue ? getPersistedInt(defaultVal) : defaultVal);
}
public void setValue(int value) {
mCurrentValue = value;
updateView();
}
private Drawable getSeekBarThumb() {
return mProgressThumb;
}
private void startUpdateViewValue() {
if (!mTrackingTouch) return;
Rect thumbRect = getSeekBarThumb().getBounds();
int[] seekbarPos = new int[2];
int[] offsetPos = new int[2];
mSeekBar.getLocationInWindow(seekbarPos);
View mainContentView = /*mSeekBar.getRootView().findViewById(R.id.content_main);
if (mainContentView == null) {
mainContentView =*/ mSeekBar.getRootView().findViewById(android.R.id.content);
//}
if (mainContentView == null) {
Log.w(TAG, "Could not find main content view to calculate value view offset");
offsetPos[0] = 0;
offsetPos[1] = 0;
} else {
mainContentView.getLocationInWindow(offsetPos);
}
mPopupValue.setText(mUnitsLeft + mCurrentValue + mUnitsRight);
WindowManager.LayoutParams wp = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
wp.gravity = Gravity.LEFT | Gravity.TOP;
wp.x = thumbRect.centerX() + seekbarPos[0] - offsetPos[0] - (mPopupWidth-thumbRect.width()) / 2 +
(int) getContext().getResources()
.getDimension(R.dimen.seek_bar_preference_cham_value_x_offset);
wp.y = seekbarPos[1] - offsetPos[1] +
(int) getContext().getResources()
.getDimension(R.dimen.seek_bar_preference_cham_value_y_offset);
mPopupValue.setLayoutParams(wp);
if (mPopupAdded) {
wp = (WindowManager.LayoutParams) mPopupValue.getLayoutParams();
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE))
.updateViewLayout(mPopupValue, wp);
} else {
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE))
.addView(mPopupValue, wp);
mPopupAdded = true;
}
mPopupValue.setVisibility(View.VISIBLE);
}
private void stopUpdateViewValue() {
if (!mPopupAdded) return;
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).removeView(mPopupValue);
mPopupAdded = false;
}
public void setMax(int max) {
mMaxValue = max;
updateView();
}
public void setMin(int min) {
mMinValue = min;
updateView();
}
@Override
public void setDefaultValue(Object defaultValue) {
super.setDefaultValue(defaultValue);
if (defaultValue instanceof Integer) {
mDefaultValue = (Integer) defaultValue;
updateView();
}
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2017 AICP
*
* 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.text.TextUtils;
import android.util.AttributeSet;
import androidx.preference.EditTextPreference;
public class SystemSettingEditTextPreference extends EditTextPreference {
private boolean mAutoSummary = false;
public SystemSettingEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
public SystemSettingEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
public SystemSettingEditTextPreference(Context context) {
super(context);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
// This is what default ListPreference implementation is doing without respecting
// real default value:
//setText(restoreValue ? getPersistedString(mText) : (String) defaultValue);
// Instead, we better do
setText(restoreValue ? getPersistedString((String) defaultValue) : (String) defaultValue);
}
@Override
public void setText(String text) {
super.setText(text);
if (mAutoSummary || TextUtils.isEmpty(getSummary())) {
setSummary(text, true);
}
}
@Override
public void setSummary(CharSequence summary) {
setSummary(summary, false);
}
private void setSummary(CharSequence summary, boolean autoSummary) {
mAutoSummary = autoSummary;
super.setSummary(summary);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2017 AICP
*
* 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.util.AttributeSet;
public class SystemSettingIntListPreference extends SystemSettingListPreference {
public SystemSettingIntListPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SystemSettingIntListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SystemSettingIntListPreference(Context context) {
super(context);
}
@Override
protected boolean persistString(String value) {
return persistInt(Integer.parseInt(value));
}
@Override
protected String getPersistedString(String defaultReturnValue) {
return String.valueOf(getPersistedInt(Integer.parseInt(defaultReturnValue)));
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2017-2018 AICP
*
* 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.text.TextUtils;
import android.util.AttributeSet;
public class SystemSettingListPreference extends ListPreference {
public SystemSettingListPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
public SystemSettingListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
public SystemSettingListPreference(Context context) {
super(context);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
// This is what default ListPreference implementation is doing without respecting
// real default value:
//setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
// Instead, we better do
setValue(restoreValue ? getPersistedString((String) defaultValue) : (String) defaultValue);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2017 AICP
*
* 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.util.AttributeSet;
public class SystemSettingSeekBarPreference extends SeekBarPreferenceCham {
public SystemSettingSeekBarPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
public SystemSettingSeekBarPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
public SystemSettingSeekBarPreference(Context context) {
super(context, null);
setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));
}
}