diff --git a/res/values/dimens.xml b/res/values/dimens.xml index c2fd7335bd..b90f3a7f4a 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -35,6 +35,7 @@ 8dp 56dp 8dp + 16dp 8dp diff --git a/src/org/thoughtcrime/securesms/loki/activities/PathActivity.kt b/src/org/thoughtcrime/securesms/loki/activities/PathActivity.kt index ff1a63e080..96ebc1f789 100644 --- a/src/org/thoughtcrime/securesms/loki/activities/PathActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/activities/PathActivity.kt @@ -1,7 +1,11 @@ package org.thoughtcrime.securesms.loki.activities +import android.animation.FloatEvaluator +import android.animation.ValueAnimator import android.content.Context import android.os.Bundle +import android.os.Handler +import android.support.annotation.DimenRes import android.util.AttributeSet import android.util.TypedValue import android.view.Gravity @@ -13,6 +17,7 @@ import kotlinx.android.synthetic.main.activity_path.* import network.loki.messenger.R import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.loki.utilities.getColorWithID +import org.thoughtcrime.securesms.loki.views.NewConversationButtonSetView class PathActivity : PassphraseRequiredActionBarActivity() { @@ -21,11 +26,11 @@ class PathActivity : PassphraseRequiredActionBarActivity() { super.onCreate(savedInstanceState, isReady) setContentView(R.layout.activity_path) supportActionBar!!.title = resources.getString(R.string.activity_path_title) - val youRow = getPathRow("You", null, LineView.Location.Top, 0.0f, 0.0f) - val row1 = getPathRow("Guard Node", "0.0.0.0", LineView.Location.Middle, 0.0f, 0.0f) - val row2 = getPathRow("Service Node", "0.0.0.0", LineView.Location.Middle, 0.0f, 0.0f) - val row3 = getPathRow("Service Node", "0.0.0.0", LineView.Location.Middle, 0.0f, 0.0f) - val destinationRow = getPathRow("Destination", null, LineView.Location.Bottom, 0.0f, 0.0f) + val youRow = getPathRow("You", null, LineView.Location.Top, 1000, 4000) + val row1 = getPathRow("Guard Node", "0.0.0.0", LineView.Location.Middle, 2000, 4000) + val row2 = getPathRow("Service Node", "0.0.0.0", LineView.Location.Middle, 3000, 4000) + val row3 = getPathRow("Service Node", "0.0.0.0", LineView.Location.Middle, 4000, 4000) + val destinationRow = getPathRow("Destination", null, LineView.Location.Bottom, 5000, 4000) pathRowsContainer.addView(youRow) pathRowsContainer.addView(row1) pathRowsContainer.addView(row2) @@ -35,9 +40,9 @@ class PathActivity : PassphraseRequiredActionBarActivity() { // endregion // region General - private fun getPathRow(title: String, subtitle: String?, location: LineView.Location, dotAnimationStartDelay: Float, dotAnimationRepeatInterval: Float): LinearLayout { + private fun getPathRow(title: String, subtitle: String?, location: LineView.Location, dotAnimationStartDelay: Long, dotAnimationRepeatInterval: Long): LinearLayout { val lineView = LineView(this, location, dotAnimationStartDelay, dotAnimationRepeatInterval) - val lineViewLayoutParams = LinearLayout.LayoutParams(resources.getDimensionPixelSize(R.dimen.path_row_dot_size), resources.getDimensionPixelSize(R.dimen.path_row_height)) + val lineViewLayoutParams = LinearLayout.LayoutParams(resources.getDimensionPixelSize(R.dimen.path_row_expanded_dot_size), resources.getDimensionPixelSize(R.dimen.path_row_height)) lineView.layoutParams = lineViewLayoutParams val titleTextView = TextView(this) titleTextView.setTextColor(resources.getColorWithID(R.color.text, theme)) @@ -70,14 +75,20 @@ class PathActivity : PassphraseRequiredActionBarActivity() { // region Line View private class LineView : RelativeLayout { private lateinit var location: Location - private var dotAnimationStartDelay = 0.0f - private var dotAnimationRepeatInterval = 0.0f + private var dotAnimationStartDelay: Long = 0 + private var dotAnimationRepeatInterval: Long = 0 + + private val dotView by lazy { + val result = View(context) + result.setBackgroundResource(R.drawable.accent_dot) + result + } enum class Location { Top, Middle, Bottom } - constructor(context: Context, location: Location, dotAnimationStartDelay: Float, dotAnimationRepeatInterval: Float) : super(context) { + constructor(context: Context, location: Location, dotAnimationStartDelay: Long, dotAnimationRepeatInterval: Long) : super(context) { this.location = location this.dotAnimationStartDelay = dotAnimationStartDelay this.dotAnimationRepeatInterval = dotAnimationRepeatInterval @@ -115,13 +126,47 @@ class PathActivity : PassphraseRequiredActionBarActivity() { lineViewLayoutParams.addRule(CENTER_HORIZONTAL) lineView.layoutParams = lineViewLayoutParams addView(lineView) - val dotView = View(context) - dotView.setBackgroundResource(R.drawable.accent_dot) val dotViewSize = resources.getDimensionPixelSize(R.dimen.path_row_dot_size) val dotViewLayoutParams = LayoutParams(dotViewSize, dotViewSize) dotViewLayoutParams.addRule(CENTER_IN_PARENT) dotView.layoutParams = dotViewLayoutParams addView(dotView) + Handler().postDelayed({ + performAnimation() + }, dotAnimationStartDelay) + } + + private fun performAnimation() { + expand() + Handler().postDelayed({ + collapse() + Handler().postDelayed({ + performAnimation() + }, dotAnimationRepeatInterval) + }, 1000) + } + + private fun expand() { + animateDotViewSizeChange(R.dimen.path_row_dot_size, R.dimen.path_row_expanded_dot_size) + } + + private fun collapse() { + animateDotViewSizeChange(R.dimen.path_row_expanded_dot_size, R.dimen.path_row_dot_size) + } + + private fun animateDotViewSizeChange(@DimenRes startSizeID: Int, @DimenRes endSizeID: Int) { + val layoutParams = dotView.layoutParams + val startSize = resources.getDimension(startSizeID) + val endSize = resources.getDimension(endSizeID) + val animation = ValueAnimator.ofObject(FloatEvaluator(), startSize, endSize) + animation.duration = NewConversationButtonSetView.Button.animationDuration + animation.addUpdateListener { animator -> + val size = animator.animatedValue as Float + layoutParams.width = size.toInt() + layoutParams.height = size.toInt() + dotView.layoutParams = layoutParams + } + animation.start() } } // endregion