Loading k9mail/src/main/java/com/fsck/k9/activity/compose/CryptoSettingsDialog.java +31 −19 Original line number Diff line number Diff line Loading @@ -15,24 +15,28 @@ import android.view.View; import com.fsck.k9.R; import com.fsck.k9.activity.compose.RecipientPresenter.CryptoMode; import com.fsck.k9.view.CryptoModeSelector; import com.fsck.k9.view.CryptoModeSelector.CryptoModeSelectorState; import com.fsck.k9.view.CryptoModeSelector.CryptoStatusSelectedListener; import com.fsck.k9.view.LinearViewAnimator; public class CryptoSettingsDialog extends DialogFragment implements CryptoStatusSelectedListener { private static final String ARG_CURRENT_MODE = "current_mode"; private static final String ARG_SUPPORT_SIGN_ONLY = "support_sing_only"; private static final String ARG_CURRENT_MODE = "current_override"; private CryptoModeSelector cryptoModeSelector; private LinearViewAnimator cryptoStatusText; private CryptoMode currentMode; public static CryptoSettingsDialog newInstance(CryptoMode initialOverride) { public static CryptoSettingsDialog newInstance(CryptoMode initialMode, boolean supportSignOnly) { CryptoSettingsDialog dialog = new CryptoSettingsDialog(); Bundle args = new Bundle(); args.putString(ARG_CURRENT_MODE, initialOverride.toString()); args.putString(ARG_CURRENT_MODE, initialMode.toString()); args.putBoolean(ARG_SUPPORT_SIGN_ONLY, supportSignOnly); dialog.setArguments(args); return dialog; Loading @@ -40,15 +44,18 @@ public class CryptoSettingsDialog extends DialogFragment implements CryptoStatus @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Bundle arguments = savedInstanceState != null ? savedInstanceState : getArguments(); boolean supportSignOnly = arguments.getBoolean(ARG_SUPPORT_SIGN_ONLY); currentMode = CryptoMode.valueOf(arguments.getString(ARG_CURRENT_MODE)); @SuppressLint("InflateParams") View view = LayoutInflater.from(getActivity()).inflate(R.layout.crypto_settings_dialog, null); View view = LayoutInflater.from(getActivity()).inflate(supportSignOnly ? R.layout.crypto_settings_dialog_sign_only : R.layout.crypto_settings_dialog, null); cryptoModeSelector = (CryptoModeSelector) view.findViewById(R.id.crypto_status_selector); cryptoStatusText = (LinearViewAnimator) view.findViewById(R.id.crypto_status_text); cryptoModeSelector.setCryptoStatusListener(this); Bundle arguments = savedInstanceState != null ? savedInstanceState : getArguments(); currentMode = CryptoMode.valueOf(arguments.getString(ARG_CURRENT_MODE)); updateView(false); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); Loading Loading @@ -87,19 +94,19 @@ public class CryptoSettingsDialog extends DialogFragment implements CryptoStatus void updateView(boolean animate) { switch (currentMode) { case DISABLE: cryptoModeSelector.setCryptoStatus(0); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.DISABLED); cryptoStatusText.setDisplayedChild(0, animate); break; case SIGN_ONLY: cryptoModeSelector.setCryptoStatus(1); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.SIGN_ONLY); cryptoStatusText.setDisplayedChild(1, animate); break; case OPPORTUNISTIC: cryptoModeSelector.setCryptoStatus(2); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.OPPORTUNISTIC); cryptoStatusText.setDisplayedChild(2, animate); break; case PRIVATE: cryptoModeSelector.setCryptoStatus(3); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.PRIVATE); cryptoStatusText.setDisplayedChild(3, animate); break; } Loading @@ -113,15 +120,20 @@ public class CryptoSettingsDialog extends DialogFragment implements CryptoStatus } @Override public void onCryptoStatusSelected(int status) { if (status == 0) { public void onCryptoStatusSelected(CryptoModeSelectorState status) { switch (status) { case DISABLED: currentMode = CryptoMode.DISABLE; } else if (status == 1) { break; case SIGN_ONLY: currentMode = CryptoMode.SIGN_ONLY; } else if (status == 2) { break; case OPPORTUNISTIC: currentMode = CryptoMode.OPPORTUNISTIC; } else { break; case PRIVATE: currentMode = CryptoMode.PRIVATE; break; } updateView(true); } Loading k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientMvpView.java +2 −2 Original line number Diff line number Diff line Loading @@ -378,8 +378,8 @@ public class RecipientMvpView implements OnFocusChangeListener, OnClickListener } } public void showCryptoDialog(CryptoMode currentCryptoMode) { CryptoSettingsDialog dialog = CryptoSettingsDialog.newInstance(currentCryptoMode); public void showCryptoDialog(CryptoMode currentCryptoMode, boolean supportSignOnly) { CryptoSettingsDialog dialog = CryptoSettingsDialog.newInstance(currentCryptoMode, supportSignOnly); dialog.show(activity.getFragmentManager(), "crypto_settings"); } Loading k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.java +1 −1 Original line number Diff line number Diff line Loading @@ -545,7 +545,7 @@ public class RecipientPresenter implements PermissionPingCallback { Log.e(K9.LOG_TAG, "click on crypto status while unconfigured - this should not really happen?!"); return; case OK: recipientMvpView.showCryptoDialog(currentCryptoMode); recipientMvpView.showCryptoDialog(currentCryptoMode, account.getCryptoSupportSignOnly()); return; case LOST_CONNECTION: Loading k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoPresenter.java +5 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,11 @@ public class MessageCryptoPresenter implements OnCryptoClickListener { return false; } boolean suppressSignOnlyMessages = !account.getCryptoSupportSignOnly(); if (suppressSignOnlyMessages && displayStatus.isUnencryptedSigned()) { return false; } messageView.getMessageHeaderView().setCryptoStatus(displayStatus); switch (displayStatus) { Loading k9mail/src/main/java/com/fsck/k9/view/CryptoModeSelector.java +7 −163 Original line number Diff line number Diff line package com.fsck.k9.view; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.PorterDuff; import android.util.AttributeSet; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import com.fsck.k9.R; public class CryptoModeSelector extends FrameLayout implements OnSeekBarChangeListener { public static final int CROSSFADE_THRESH_1_LOW = -50; public static final int CROSSFADE_THRESH_1_HIGH = 50; public static final int CROSSFADE_THRESH_2_LOW = 50; public static final int CROSSFADE_THRESH_2_HIGH = 150; public static final int CROSSFADE_THRESH_3_LOW = 150; public static final int CROSSFADE_THRESH_3_HIGH = 250; public static final int CROSSFADE_THRESH_4_LOW = 250; public static final float CROSSFADE_DIVISOR_1 = 50.0f; public static final float CROSSFADE_DIVISOR_2 = 50.0f; public static final float CROSSFADE_DIVISOR_3 = 50.0f; public static final float CROSSFADE_DIVISOR_4 = 50.0f; private SeekBar seekbar; private ImageView modeIcon1; private ImageView modeIcon2; private ImageView modeIcon3; private ImageView modeIcon4; private ObjectAnimator currentSeekbarAnim; private int currentCryptoStatus; private CryptoStatusSelectedListener cryptoStatusListener; private static final ArgbEvaluator ARGB_EVALUATOR = new ArgbEvaluator(); public abstract class CryptoModeSelector extends FrameLayout { public CryptoModeSelector(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CryptoModeSelector(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public void init() { inflate(getContext(), R.layout.crypto_mode_selector, this); seekbar = (SeekBar) findViewById(R.id.seek_bar); modeIcon1 = (ImageView) findViewById(R.id.icon_1); modeIcon2 = (ImageView) findViewById(R.id.icon_2); modeIcon3 = (ImageView) findViewById(R.id.icon_3); modeIcon4 = (ImageView) findViewById(R.id.icon_4); seekbar.setOnSeekBarChangeListener(this); onProgressChanged(seekbar, seekbar.getProgress(), false); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int grey = ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_grey); float crossfadeValue1, crossfadeValue2, crossfadeValue3, crossfadeValue4; if (progress < CROSSFADE_THRESH_1_HIGH) { crossfadeValue1 = (progress -CROSSFADE_THRESH_1_LOW) / CROSSFADE_DIVISOR_1; if (crossfadeValue1 > 1.0f) { crossfadeValue1 = 2.0f -crossfadeValue1; } } else { crossfadeValue1 = 0.0f; } if (progress > CROSSFADE_THRESH_2_LOW && progress < CROSSFADE_THRESH_2_HIGH) { crossfadeValue2 = (progress -CROSSFADE_THRESH_2_LOW) / CROSSFADE_DIVISOR_2; if (crossfadeValue2 > 1.0f) { crossfadeValue2 = 2.0f -crossfadeValue2; } } else { crossfadeValue2 = 0.0f; } if (progress > CROSSFADE_THRESH_3_LOW && progress < CROSSFADE_THRESH_3_HIGH) { crossfadeValue3 = (progress -CROSSFADE_THRESH_3_LOW) / CROSSFADE_DIVISOR_3; if (crossfadeValue3 > 1.0f) { crossfadeValue3 = 2.0f -crossfadeValue3; } } else { crossfadeValue3 = 0.0f; } if (progress > CROSSFADE_THRESH_4_LOW) { crossfadeValue4 = (progress -CROSSFADE_THRESH_4_LOW) / CROSSFADE_DIVISOR_4; } else { crossfadeValue4 = 0.0f; } int crossfadedColor; crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_dark_grey), crossfadeValue1); modeIcon1.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_blue), crossfadeValue2); modeIcon2.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_orange), crossfadeValue3); modeIcon3.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_green), crossfadeValue4); modeIcon4.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { int newCryptoStatus; int progress = seekbar.getProgress(); if (progress < 50) { animateSnapTo(0); newCryptoStatus = 0; } else if (progress < 150) { animateSnapTo(100); newCryptoStatus = 1; } else if (progress < 250) { animateSnapTo(200); newCryptoStatus = 2; } else { animateSnapTo(300); newCryptoStatus = 3; } if (currentCryptoStatus != newCryptoStatus) { currentCryptoStatus = newCryptoStatus; cryptoStatusListener.onCryptoStatusSelected(newCryptoStatus); } } private void animateSnapTo(int value) { if (currentSeekbarAnim != null) { currentSeekbarAnim.cancel(); } currentSeekbarAnim = ObjectAnimator.ofInt(seekbar, "progress", seekbar.getProgress(), value); currentSeekbarAnim.setDuration(150); currentSeekbarAnim.start(); } public static int crossfadeColor(int color1, int color2, float factor) { return (Integer) ARGB_EVALUATOR.evaluate(factor, color1, color2); } public void setCryptoStatusListener(CryptoStatusSelectedListener cryptoStatusListener) { this.cryptoStatusListener = cryptoStatusListener; } public abstract void setCryptoStatusListener(CryptoStatusSelectedListener cryptoStatusListener); public void setCryptoStatus(int status) { currentCryptoStatus = status; if (status == 0) { seekbar.setProgress(0); } else if (status == 1) { seekbar.setProgress(100); } else if (status == 2) { seekbar.setProgress(200); } else { seekbar.setProgress(300); } } public abstract void setCryptoStatus(CryptoModeSelectorState status); public interface CryptoStatusSelectedListener { void onCryptoStatusSelected(int type); void onCryptoStatusSelected(CryptoModeSelectorState type); } public enum CryptoModeSelectorState { DISABLED, SIGN_ONLY, OPPORTUNISTIC, PRIVATE } } Loading
k9mail/src/main/java/com/fsck/k9/activity/compose/CryptoSettingsDialog.java +31 −19 Original line number Diff line number Diff line Loading @@ -15,24 +15,28 @@ import android.view.View; import com.fsck.k9.R; import com.fsck.k9.activity.compose.RecipientPresenter.CryptoMode; import com.fsck.k9.view.CryptoModeSelector; import com.fsck.k9.view.CryptoModeSelector.CryptoModeSelectorState; import com.fsck.k9.view.CryptoModeSelector.CryptoStatusSelectedListener; import com.fsck.k9.view.LinearViewAnimator; public class CryptoSettingsDialog extends DialogFragment implements CryptoStatusSelectedListener { private static final String ARG_CURRENT_MODE = "current_mode"; private static final String ARG_SUPPORT_SIGN_ONLY = "support_sing_only"; private static final String ARG_CURRENT_MODE = "current_override"; private CryptoModeSelector cryptoModeSelector; private LinearViewAnimator cryptoStatusText; private CryptoMode currentMode; public static CryptoSettingsDialog newInstance(CryptoMode initialOverride) { public static CryptoSettingsDialog newInstance(CryptoMode initialMode, boolean supportSignOnly) { CryptoSettingsDialog dialog = new CryptoSettingsDialog(); Bundle args = new Bundle(); args.putString(ARG_CURRENT_MODE, initialOverride.toString()); args.putString(ARG_CURRENT_MODE, initialMode.toString()); args.putBoolean(ARG_SUPPORT_SIGN_ONLY, supportSignOnly); dialog.setArguments(args); return dialog; Loading @@ -40,15 +44,18 @@ public class CryptoSettingsDialog extends DialogFragment implements CryptoStatus @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Bundle arguments = savedInstanceState != null ? savedInstanceState : getArguments(); boolean supportSignOnly = arguments.getBoolean(ARG_SUPPORT_SIGN_ONLY); currentMode = CryptoMode.valueOf(arguments.getString(ARG_CURRENT_MODE)); @SuppressLint("InflateParams") View view = LayoutInflater.from(getActivity()).inflate(R.layout.crypto_settings_dialog, null); View view = LayoutInflater.from(getActivity()).inflate(supportSignOnly ? R.layout.crypto_settings_dialog_sign_only : R.layout.crypto_settings_dialog, null); cryptoModeSelector = (CryptoModeSelector) view.findViewById(R.id.crypto_status_selector); cryptoStatusText = (LinearViewAnimator) view.findViewById(R.id.crypto_status_text); cryptoModeSelector.setCryptoStatusListener(this); Bundle arguments = savedInstanceState != null ? savedInstanceState : getArguments(); currentMode = CryptoMode.valueOf(arguments.getString(ARG_CURRENT_MODE)); updateView(false); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); Loading Loading @@ -87,19 +94,19 @@ public class CryptoSettingsDialog extends DialogFragment implements CryptoStatus void updateView(boolean animate) { switch (currentMode) { case DISABLE: cryptoModeSelector.setCryptoStatus(0); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.DISABLED); cryptoStatusText.setDisplayedChild(0, animate); break; case SIGN_ONLY: cryptoModeSelector.setCryptoStatus(1); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.SIGN_ONLY); cryptoStatusText.setDisplayedChild(1, animate); break; case OPPORTUNISTIC: cryptoModeSelector.setCryptoStatus(2); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.OPPORTUNISTIC); cryptoStatusText.setDisplayedChild(2, animate); break; case PRIVATE: cryptoModeSelector.setCryptoStatus(3); cryptoModeSelector.setCryptoStatus(CryptoModeSelectorState.PRIVATE); cryptoStatusText.setDisplayedChild(3, animate); break; } Loading @@ -113,15 +120,20 @@ public class CryptoSettingsDialog extends DialogFragment implements CryptoStatus } @Override public void onCryptoStatusSelected(int status) { if (status == 0) { public void onCryptoStatusSelected(CryptoModeSelectorState status) { switch (status) { case DISABLED: currentMode = CryptoMode.DISABLE; } else if (status == 1) { break; case SIGN_ONLY: currentMode = CryptoMode.SIGN_ONLY; } else if (status == 2) { break; case OPPORTUNISTIC: currentMode = CryptoMode.OPPORTUNISTIC; } else { break; case PRIVATE: currentMode = CryptoMode.PRIVATE; break; } updateView(true); } Loading
k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientMvpView.java +2 −2 Original line number Diff line number Diff line Loading @@ -378,8 +378,8 @@ public class RecipientMvpView implements OnFocusChangeListener, OnClickListener } } public void showCryptoDialog(CryptoMode currentCryptoMode) { CryptoSettingsDialog dialog = CryptoSettingsDialog.newInstance(currentCryptoMode); public void showCryptoDialog(CryptoMode currentCryptoMode, boolean supportSignOnly) { CryptoSettingsDialog dialog = CryptoSettingsDialog.newInstance(currentCryptoMode, supportSignOnly); dialog.show(activity.getFragmentManager(), "crypto_settings"); } Loading
k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.java +1 −1 Original line number Diff line number Diff line Loading @@ -545,7 +545,7 @@ public class RecipientPresenter implements PermissionPingCallback { Log.e(K9.LOG_TAG, "click on crypto status while unconfigured - this should not really happen?!"); return; case OK: recipientMvpView.showCryptoDialog(currentCryptoMode); recipientMvpView.showCryptoDialog(currentCryptoMode, account.getCryptoSupportSignOnly()); return; case LOST_CONNECTION: Loading
k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoPresenter.java +5 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,11 @@ public class MessageCryptoPresenter implements OnCryptoClickListener { return false; } boolean suppressSignOnlyMessages = !account.getCryptoSupportSignOnly(); if (suppressSignOnlyMessages && displayStatus.isUnencryptedSigned()) { return false; } messageView.getMessageHeaderView().setCryptoStatus(displayStatus); switch (displayStatus) { Loading
k9mail/src/main/java/com/fsck/k9/view/CryptoModeSelector.java +7 −163 Original line number Diff line number Diff line package com.fsck.k9.view; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.PorterDuff; import android.util.AttributeSet; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import com.fsck.k9.R; public class CryptoModeSelector extends FrameLayout implements OnSeekBarChangeListener { public static final int CROSSFADE_THRESH_1_LOW = -50; public static final int CROSSFADE_THRESH_1_HIGH = 50; public static final int CROSSFADE_THRESH_2_LOW = 50; public static final int CROSSFADE_THRESH_2_HIGH = 150; public static final int CROSSFADE_THRESH_3_LOW = 150; public static final int CROSSFADE_THRESH_3_HIGH = 250; public static final int CROSSFADE_THRESH_4_LOW = 250; public static final float CROSSFADE_DIVISOR_1 = 50.0f; public static final float CROSSFADE_DIVISOR_2 = 50.0f; public static final float CROSSFADE_DIVISOR_3 = 50.0f; public static final float CROSSFADE_DIVISOR_4 = 50.0f; private SeekBar seekbar; private ImageView modeIcon1; private ImageView modeIcon2; private ImageView modeIcon3; private ImageView modeIcon4; private ObjectAnimator currentSeekbarAnim; private int currentCryptoStatus; private CryptoStatusSelectedListener cryptoStatusListener; private static final ArgbEvaluator ARGB_EVALUATOR = new ArgbEvaluator(); public abstract class CryptoModeSelector extends FrameLayout { public CryptoModeSelector(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CryptoModeSelector(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public void init() { inflate(getContext(), R.layout.crypto_mode_selector, this); seekbar = (SeekBar) findViewById(R.id.seek_bar); modeIcon1 = (ImageView) findViewById(R.id.icon_1); modeIcon2 = (ImageView) findViewById(R.id.icon_2); modeIcon3 = (ImageView) findViewById(R.id.icon_3); modeIcon4 = (ImageView) findViewById(R.id.icon_4); seekbar.setOnSeekBarChangeListener(this); onProgressChanged(seekbar, seekbar.getProgress(), false); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int grey = ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_grey); float crossfadeValue1, crossfadeValue2, crossfadeValue3, crossfadeValue4; if (progress < CROSSFADE_THRESH_1_HIGH) { crossfadeValue1 = (progress -CROSSFADE_THRESH_1_LOW) / CROSSFADE_DIVISOR_1; if (crossfadeValue1 > 1.0f) { crossfadeValue1 = 2.0f -crossfadeValue1; } } else { crossfadeValue1 = 0.0f; } if (progress > CROSSFADE_THRESH_2_LOW && progress < CROSSFADE_THRESH_2_HIGH) { crossfadeValue2 = (progress -CROSSFADE_THRESH_2_LOW) / CROSSFADE_DIVISOR_2; if (crossfadeValue2 > 1.0f) { crossfadeValue2 = 2.0f -crossfadeValue2; } } else { crossfadeValue2 = 0.0f; } if (progress > CROSSFADE_THRESH_3_LOW && progress < CROSSFADE_THRESH_3_HIGH) { crossfadeValue3 = (progress -CROSSFADE_THRESH_3_LOW) / CROSSFADE_DIVISOR_3; if (crossfadeValue3 > 1.0f) { crossfadeValue3 = 2.0f -crossfadeValue3; } } else { crossfadeValue3 = 0.0f; } if (progress > CROSSFADE_THRESH_4_LOW) { crossfadeValue4 = (progress -CROSSFADE_THRESH_4_LOW) / CROSSFADE_DIVISOR_4; } else { crossfadeValue4 = 0.0f; } int crossfadedColor; crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_dark_grey), crossfadeValue1); modeIcon1.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_blue), crossfadeValue2); modeIcon2.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_orange), crossfadeValue3); modeIcon3.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); crossfadedColor = crossfadeColor(grey, ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_green), crossfadeValue4); modeIcon4.setColorFilter(crossfadedColor, PorterDuff.Mode.SRC_ATOP); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { int newCryptoStatus; int progress = seekbar.getProgress(); if (progress < 50) { animateSnapTo(0); newCryptoStatus = 0; } else if (progress < 150) { animateSnapTo(100); newCryptoStatus = 1; } else if (progress < 250) { animateSnapTo(200); newCryptoStatus = 2; } else { animateSnapTo(300); newCryptoStatus = 3; } if (currentCryptoStatus != newCryptoStatus) { currentCryptoStatus = newCryptoStatus; cryptoStatusListener.onCryptoStatusSelected(newCryptoStatus); } } private void animateSnapTo(int value) { if (currentSeekbarAnim != null) { currentSeekbarAnim.cancel(); } currentSeekbarAnim = ObjectAnimator.ofInt(seekbar, "progress", seekbar.getProgress(), value); currentSeekbarAnim.setDuration(150); currentSeekbarAnim.start(); } public static int crossfadeColor(int color1, int color2, float factor) { return (Integer) ARGB_EVALUATOR.evaluate(factor, color1, color2); } public void setCryptoStatusListener(CryptoStatusSelectedListener cryptoStatusListener) { this.cryptoStatusListener = cryptoStatusListener; } public abstract void setCryptoStatusListener(CryptoStatusSelectedListener cryptoStatusListener); public void setCryptoStatus(int status) { currentCryptoStatus = status; if (status == 0) { seekbar.setProgress(0); } else if (status == 1) { seekbar.setProgress(100); } else if (status == 2) { seekbar.setProgress(200); } else { seekbar.setProgress(300); } } public abstract void setCryptoStatus(CryptoModeSelectorState status); public interface CryptoStatusSelectedListener { void onCryptoStatusSelected(int type); void onCryptoStatusSelected(CryptoModeSelectorState type); } public enum CryptoModeSelectorState { DISABLED, SIGN_ONLY, OPPORTUNISTIC, PRIVATE } }