From ef519a858143260c1bd0fd3eadfc9fde56a718ac Mon Sep 17 00:00:00 2001 From: Mygod Date: Tue, 19 Dec 2017 17:31:09 -0800 Subject: [PATCH] Clean up ServiceButton related code --- .../com/github/shadowsocks/MainActivity.kt | 20 +------ .../shadowsocks/widget/ServiceButton.kt | 59 ++++++++++++++----- .../src/main/res/color/background_service.xml | 5 ++ mobile/src/main/res/layout/layout_main.xml | 4 +- 4 files changed, 53 insertions(+), 35 deletions(-) create mode 100644 mobile/src/main/res/color/background_service.xml diff --git a/mobile/src/main/java/com/github/shadowsocks/MainActivity.kt b/mobile/src/main/java/com/github/shadowsocks/MainActivity.kt index 665910dc..d64123b4 100644 --- a/mobile/src/main/java/com/github/shadowsocks/MainActivity.kt +++ b/mobile/src/main/java/com/github/shadowsocks/MainActivity.kt @@ -31,14 +31,12 @@ import android.nfc.NfcAdapter import android.os.Bundle import android.os.SystemClock import android.support.customtabs.CustomTabsIntent -import android.support.design.widget.FloatingActionButton import android.support.design.widget.Snackbar import android.support.v4.content.ContextCompat import android.support.v7.app.AlertDialog import android.support.v7.app.AppCompatActivity import android.support.v7.content.res.AppCompatResources import android.support.v7.preference.PreferenceDataStore -import android.support.v7.widget.TooltipCompat import android.util.Log import android.view.View import android.widget.TextView @@ -87,8 +85,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, Drawe } // UI - private lateinit var fab: FloatingActionButton - private val fabHelper by lazy { ServiceButton(fab) } + private lateinit var fab: ServiceButton internal var crossfader: Crossfader? = null internal lateinit var drawer: Drawer private var previousSelectedDrawer: Long = 0 // it's actually lateinit @@ -110,9 +107,6 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, Drawe } catch (_: ActivityNotFoundException) { } // ignore fun launchUrl(uri: String) = launchUrl(Uri.parse(uri)) - private val greyTint by lazy { ContextCompat.getColorStateList(this, R.color.material_primary_500) } - private val greenTint by lazy { ContextCompat.getColorStateList(this, R.color.material_green_700) } - // service var state = BaseService.IDLE override val serviceCallback: IShadowsocksServiceCallback.Stub by lazy { @@ -130,7 +124,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, Drawe } fun changeState(state: Int, msg: String? = null, animate: Boolean = false) { - fabHelper.changeState(state, animate) + fab.changeState(state, animate) when (state) { BaseService.CONNECTING -> statusText.setText(R.string.connecting) BaseService.CONNECTED -> statusText.setText(R.string.vpn_connected) @@ -145,20 +139,12 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, Drawe } } this.state = state - if (state == BaseService.CONNECTED) { - fab.backgroundTintList = greenTint - TooltipCompat.setTooltipText(fab, getString(R.string.stop)) - } else { - fab.backgroundTintList = greyTint - TooltipCompat.setTooltipText(fab, getString(R.string.connect)) + if (state != BaseService.CONNECTED) { updateTraffic(-1, 0, 0, 0, 0) testCount += 1 // suppress previous test messages } ProfilesFragment.instance?.profilesAdapter?.notifyDataSetChanged() // refresh button enabled state stateListener?.invoke(state) - fab.isEnabled = false - if (state == BaseService.CONNECTED || state == BaseService.STOPPED) app.handler.postDelayed( - { fab.isEnabled = state == BaseService.CONNECTED || state == BaseService.STOPPED }, 1000) } fun updateTraffic(profileId: Int, txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) { txText.text = TrafficMonitor.formatTraffic(txTotal) diff --git a/mobile/src/main/java/com/github/shadowsocks/widget/ServiceButton.kt b/mobile/src/main/java/com/github/shadowsocks/widget/ServiceButton.kt index 8bdda3cb..af926432 100644 --- a/mobile/src/main/java/com/github/shadowsocks/widget/ServiceButton.kt +++ b/mobile/src/main/java/com/github/shadowsocks/widget/ServiceButton.kt @@ -20,19 +20,38 @@ package com.github.shadowsocks.widget +import android.content.Context import android.graphics.drawable.Drawable import android.support.annotation.DrawableRes import android.support.design.widget.FloatingActionButton import android.support.graphics.drawable.Animatable2Compat import android.support.graphics.drawable.AnimatedVectorDrawableCompat +import android.support.v7.widget.TooltipCompat +import android.util.AttributeSet +import android.view.View +import com.github.shadowsocks.App import com.github.shadowsocks.R import com.github.shadowsocks.bg.BaseService import java.util.* -class ServiceButton(private val fab: FloatingActionButton) : Animatable2Compat.AnimationCallback() { +class ServiceButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + FloatingActionButton(context, attrs, defStyleAttr) { + private val callback = object : Animatable2Compat.AnimationCallback() { + override fun onAnimationEnd(drawable: Drawable) { + super.onAnimationEnd(drawable) + var next = animationQueue.peek() ?: return + if (next.current == drawable) { + animationQueue.pop() + next = animationQueue.peek() ?: return + } + setImageDrawable(next) + next.start() + } + } + private fun createIcon(@DrawableRes resId: Int): AnimatedVectorDrawableCompat { - val result = AnimatedVectorDrawableCompat.create(fab.context, resId)!! - result.registerAnimationCallback(this) + val result = AnimatedVectorDrawableCompat.create(context, resId)!! + result.registerAnimationCallback(callback) return result } @@ -42,6 +61,14 @@ class ServiceButton(private val fab: FloatingActionButton) : Animatable2Compat.A private val iconStopping by lazy { createIcon(R.drawable.ic_service_stopping) } private val animationQueue = ArrayDeque() + private var checked = false + + override fun onCreateDrawableState(extraSpace: Int): IntArray { + val drawableState = super.onCreateDrawableState(extraSpace + 1) + if (checked) View.mergeDrawableStates(drawableState, intArrayOf(android.R.attr.state_checked)) + return drawableState + } + fun changeState(state: Int, animate: Boolean) { when (state) { BaseService.CONNECTING -> changeState(iconConnecting, animate) @@ -49,6 +76,17 @@ class ServiceButton(private val fab: FloatingActionButton) : Animatable2Compat.A BaseService.STOPPING -> changeState(iconStopping, animate) else -> changeState(iconStopped, animate) } + if (state == BaseService.CONNECTED) { + checked = true + TooltipCompat.setTooltipText(this, context.getString(R.string.stop)) + } else { + checked = false + TooltipCompat.setTooltipText(this, context.getString(R.string.connect)) + } + refreshDrawableState() + isEnabled = false + if (state == BaseService.CONNECTED || state == BaseService.STOPPED) App.app.handler.postDelayed( + { isEnabled = state == BaseService.CONNECTED || state == BaseService.STOPPED }, 1000) } private fun counters(a: AnimatedVectorDrawableCompat, b: AnimatedVectorDrawableCompat): Boolean = @@ -62,26 +100,15 @@ class ServiceButton(private val fab: FloatingActionButton) : Animatable2Compat.A if (animationQueue.size < 2 || !counters(animationQueue.last, icon)) { animationQueue.add(icon) if (animationQueue.size == 1) { - fab.setImageDrawable(icon) + setImageDrawable(icon) icon.start() } } else animationQueue.removeLast() } else { animationQueue.peekFirst()?.stop() animationQueue.clear() - fab.setImageDrawable(icon) + setImageDrawable(icon) icon.stop() } } - - override fun onAnimationEnd(drawable: Drawable) { - super.onAnimationEnd(drawable) - var next = animationQueue.peek() ?: return - if (next.current == drawable) { - animationQueue.pop() - next = animationQueue.peek() ?: return - } - fab.setImageDrawable(next) - next.start() - } } diff --git a/mobile/src/main/res/color/background_service.xml b/mobile/src/main/res/color/background_service.xml new file mode 100644 index 00000000..280303d4 --- /dev/null +++ b/mobile/src/main/res/color/background_service.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/mobile/src/main/res/layout/layout_main.xml b/mobile/src/main/res/layout/layout_main.xml index d3c12937..26f26644 100644 --- a/mobile/src/main/res/layout/layout_main.xml +++ b/mobile/src/main/res/layout/layout_main.xml @@ -77,11 +77,11 @@ android:layout_marginEnd="16dp" android:layout_marginTop="-28dp" android:elevation="6dp"> -