1 /** 2 * Copyright (C) 2015 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 com.android.settings.notification; 18 19 import com.android.settings.R; 20 import com.android.settings.SeekBarPreference; 21 22 import android.content.Context; 23 import android.content.res.ColorStateList; 24 import android.content.res.TypedArray; 25 import android.graphics.drawable.Drawable; 26 import android.os.Handler; 27 import android.service.notification.NotificationListenerService; 28 import android.support.v7.preference.PreferenceViewHolder; 29 import android.util.AttributeSet; 30 import android.view.View; 31 import android.widget.ImageView; 32 import android.widget.SeekBar; 33 import android.widget.TextView; 34 import com.android.settings.Utils; 35 36 /** 37 * A slider preference that controls notification importance. 38 **/ 39 public class ImportanceSeekBarPreference extends SeekBarPreference implements 40 SeekBar.OnSeekBarChangeListener { 41 private static final String TAG = "ImportanceSeekBarPref"; 42 43 private Callback mCallback; 44 private int mMinProgress; 45 private TextView mSummaryTextView; 46 private String mSummary; 47 private SeekBar mSeekBar; 48 private ColorStateList mActiveSliderTint; 49 private ColorStateList mInactiveSliderTint; 50 private float mActiveSliderAlpha = 1.0f; 51 private float mInactiveSliderAlpha; 52 private boolean mAutoOn; 53 private Handler mHandler; 54 55 public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, 56 int defStyleRes) { 57 super(context, attrs, defStyleAttr, defStyleRes); 58 setLayoutResource(R.layout.preference_importance_slider); 59 mActiveSliderTint = ColorStateList.valueOf(Utils.getColorAccent(context)); 60 mInactiveSliderTint = ColorStateList.valueOf( 61 context.getColor(R.color.importance_disabled_slider_color)); 62 mHandler = new Handler(); 63 final TypedArray ta = 64 context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Theme, 0, 0); 65 mInactiveSliderAlpha = 66 ta.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f); 67 ta.recycle(); 68 } 69 70 public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) { 71 this(context, attrs, defStyleAttr, 0); 72 } 73 74 public ImportanceSeekBarPreference(Context context, AttributeSet attrs) { 75 this(context, attrs, 0); 76 } 77 78 public ImportanceSeekBarPreference(Context context) { 79 this(context, null); 80 } 81 82 public void setCallback(Callback callback) { 83 mCallback = callback; 84 } 85 86 public void setMinimumProgress(int minProgress) { 87 mMinProgress = minProgress; 88 notifyChanged(); 89 } 90 91 @Override 92 public void setProgress(int progress) { 93 mSummary = getProgressSummary(progress); 94 super.setProgress(progress); 95 } 96 97 public void setAutoOn(boolean autoOn) { 98 mAutoOn = autoOn; 99 notifyChanged(); 100 } 101 102 @Override 103 public void onBindViewHolder(PreferenceViewHolder view) { 104 super.onBindViewHolder(view); 105 mSummaryTextView = (TextView) view.findViewById(com.android.internal.R.id.summary); 106 mSeekBar = (SeekBar) view.findViewById( 107 com.android.internal.R.id.seekbar); 108 109 final ImageView autoButton = (ImageView) view.findViewById(R.id.auto_importance); 110 applyAutoUi(autoButton); 111 autoButton.setOnClickListener(new View.OnClickListener() { 112 @Override 113 public void onClick(View v) { 114 applyAuto(autoButton); 115 } 116 }); 117 } 118 119 private void applyAuto(ImageView autoButton) { 120 mAutoOn = !mAutoOn; 121 if (!mAutoOn) { 122 setProgress(NotificationListenerService.Ranking.IMPORTANCE_DEFAULT); 123 mCallback.onImportanceChanged( 124 NotificationListenerService.Ranking.IMPORTANCE_DEFAULT, true); 125 } else { 126 mCallback.onImportanceChanged( 127 NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED, true); 128 } 129 applyAutoUi(autoButton); 130 } 131 132 private void applyAutoUi(ImageView autoButton) { 133 mSeekBar.setEnabled(!mAutoOn); 134 135 final float alpha = mAutoOn ? mInactiveSliderAlpha : mActiveSliderAlpha; 136 final ColorStateList starTint = mAutoOn ? mActiveSliderTint : mInactiveSliderTint; 137 Drawable icon = autoButton.getDrawable().mutate(); 138 icon.setTintList(starTint); 139 autoButton.setImageDrawable(icon); 140 mSeekBar.setAlpha(alpha); 141 142 if (mAutoOn) { 143 setProgress(NotificationListenerService.Ranking.IMPORTANCE_DEFAULT); 144 mSummary = getProgressSummary( 145 NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED); 146 } 147 mSummaryTextView.setText(mSummary); 148 } 149 150 @Override 151 public CharSequence getSummary() { 152 return mSummary; 153 } 154 155 @Override 156 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { 157 super.onProgressChanged(seekBar, progress, fromTouch); 158 if (progress < mMinProgress) { 159 seekBar.setProgress(mMinProgress); 160 progress = mMinProgress; 161 } 162 if (mSummaryTextView != null) { 163 mSummary = getProgressSummary(progress); 164 mSummaryTextView.setText(mSummary); 165 } 166 mCallback.onImportanceChanged(progress, fromTouch); 167 } 168 169 private String getProgressSummary(int progress) { 170 switch (progress) { 171 case NotificationListenerService.Ranking.IMPORTANCE_NONE: 172 return getContext().getString(R.string.notification_importance_blocked); 173 case NotificationListenerService.Ranking.IMPORTANCE_MIN: 174 return getContext().getString(R.string.notification_importance_min); 175 case NotificationListenerService.Ranking.IMPORTANCE_LOW: 176 return getContext().getString(R.string.notification_importance_low); 177 case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT: 178 return getContext().getString(R.string.notification_importance_default); 179 case NotificationListenerService.Ranking.IMPORTANCE_HIGH: 180 return getContext().getString(R.string.notification_importance_high); 181 case NotificationListenerService.Ranking.IMPORTANCE_MAX: 182 return getContext().getString(R.string.notification_importance_max); 183 default: 184 return getContext().getString(R.string.notification_importance_unspecified); 185 } 186 } 187 188 @Override 189 protected void notifyChanged() { 190 mHandler.post(mNotifyChanged); 191 } 192 193 private void postNotifyChanged() { 194 super.notifyChanged(); 195 } 196 197 private final Runnable mNotifyChanged = new Runnable() { 198 @Override 199 public void run() { 200 postNotifyChanged(); 201 } 202 }; 203 204 public interface Callback { 205 void onImportanceChanged(int progress, boolean fromTouch); 206 } 207 } 208