changes before adding mock buildType
This commit is contained in:
parent
ad708e69d5
commit
e27e10315a
|
@ -0,0 +1,19 @@
|
|||
package cash.z.android.wallet.extention
|
||||
|
||||
import android.view.View
|
||||
import cash.z.android.wallet.R
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
||||
/**
|
||||
* Show a snackbar with an "OK" button
|
||||
*/
|
||||
internal inline fun Snackbar?.showOk(view: View, message: String): Snackbar {
|
||||
return if (this == null) {
|
||||
Snackbar.make(view, "$message", Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(view.context.getString(R.string.ok_allcaps)){/*auto-close*/}
|
||||
} else {
|
||||
setText(message)
|
||||
}.also {
|
||||
if (!it.isShownOrQueued) it.show()
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ object AliceWallet {
|
|||
val seedProvider = SampleSeedProvider(name)
|
||||
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||
const val cacheDbName = "testalice_cache.db"
|
||||
const val dataDbName = "testalice_data.db"
|
||||
const val dataDbName = "testalice_data8.db"
|
||||
}
|
||||
|
||||
object BobWallet {
|
||||
|
@ -15,8 +15,8 @@ object BobWallet {
|
|||
val seedProvider =
|
||||
SampleSeedProvider(name)
|
||||
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||
const val cacheDbName = "testalice_cache.db"
|
||||
const val dataDbName = "testalice_data.db"
|
||||
const val cacheDbName = "testbob_cache.db"
|
||||
const val dataDbName = "testbob_data.db"
|
||||
}
|
||||
|
||||
object MyWallet {
|
||||
|
@ -41,4 +41,12 @@ object SampleProperties {
|
|||
val COMPACT_BLOCK_SERVER = Servers.EMULATOR.host
|
||||
const val COMPACT_BLOCK_PORT = 9067
|
||||
val wallet = AliceWallet
|
||||
// TODO: placeholder until we have a network service for this
|
||||
const val USD_PER_ZEC = 49.07
|
||||
|
||||
/**
|
||||
* A simple flag that helps with removing shortcuts in the code used during development.
|
||||
* TODO: either elevate this to a real thing (based off a system property or some such) or delete it!
|
||||
*/
|
||||
const val DEV_MODE = false
|
||||
}
|
|
@ -20,6 +20,7 @@ import androidx.navigation.ui.setupWithNavController
|
|||
import cash.z.android.wallet.BuildConfig
|
||||
import cash.z.android.wallet.R
|
||||
import cash.z.android.wallet.ZcashWalletApplication
|
||||
import cash.z.android.wallet.sample.SampleProperties.DEV_MODE
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import dagger.android.support.DaggerAppCompatActivity
|
||||
|
@ -53,7 +54,7 @@ class MainActivity : BaseActivity() {
|
|||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
synchronizer.stop()
|
||||
if(!DEV_MODE)synchronizer.stop()
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
@ -66,7 +67,7 @@ class MainActivity : BaseActivity() {
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if(DEV_MODE) navController.navigate(R.id.nav_send_fragment)
|
||||
// if(DEV_MODE) navController.navigate(R.id.nav_send_fragment)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,14 +105,6 @@ class MainActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* A simple flag that helps with removing shortcuts in the code used during development.
|
||||
* TODO: either elevate this to a real thing (based off a system property or some such) or delete it!
|
||||
*/
|
||||
const val DEV_MODE = false
|
||||
|
||||
// TODO: placeholder until we have a network service for this
|
||||
const val USD_PER_ZEC = 49.07
|
||||
init {
|
||||
// Enable vector drawable magic
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package cash.z.android.wallet.ui.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.AccelerateInterpolator
|
||||
|
@ -15,19 +13,21 @@ import androidx.annotation.ColorRes
|
|||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import androidx.transition.Transition
|
||||
import androidx.transition.TransitionInflater
|
||||
import cash.z.android.wallet.R
|
||||
import cash.z.android.wallet.extention.Toaster
|
||||
import cash.z.android.wallet.extention.toAppColor
|
||||
import cash.z.android.wallet.extention.toAppString
|
||||
import cash.z.android.wallet.extention.tryIgnore
|
||||
import cash.z.android.wallet.ui.activity.MainActivity
|
||||
import cash.z.android.wallet.databinding.FragmentHomeBinding
|
||||
import cash.z.android.wallet.extention.*
|
||||
import cash.z.android.wallet.sample.SampleProperties
|
||||
import cash.z.android.wallet.sample.SampleProperties.DEV_MODE
|
||||
import cash.z.android.wallet.ui.adapter.TransactionAdapter
|
||||
import cash.z.android.wallet.ui.presenter.HomePresenter
|
||||
import cash.z.android.wallet.ui.util.AlternatingRowColorDecoration
|
||||
import cash.z.android.wallet.ui.util.LottieLooper
|
||||
import cash.z.android.wallet.ui.util.TopAlignedSpan
|
||||
import cash.z.wallet.sdk.dao.WalletTransaction
|
||||
import cash.z.wallet.sdk.data.ActiveSendTransaction
|
||||
|
@ -38,110 +38,80 @@ import com.google.android.material.snackbar.Snackbar
|
|||
import com.leinardi.android.speeddial.SpeedDialActionItem
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import kotlinx.android.synthetic.main.activity_main_first_run.*
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import kotlinx.android.synthetic.main.include_home_content.*
|
||||
import kotlinx.android.synthetic.main.include_home_header.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextLong
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
|
||||
/**
|
||||
* Fragment representing the home screen of the app. This is the screen most often seen by the user when launching the
|
||||
* application.
|
||||
*/
|
||||
class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
||||
class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomePresenter.HomeView {
|
||||
|
||||
lateinit var homePresenter: HomePresenter
|
||||
lateinit var transactionAdapter: TransactionAdapter
|
||||
private var viewsInitialized = false
|
||||
private lateinit var homePresenter: HomePresenter
|
||||
private lateinit var binding: FragmentHomeBinding
|
||||
private lateinit var zcashLogoAnimation: LottieLooper
|
||||
private var snackbar: Snackbar? = null
|
||||
private var viewsInitialized = false
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
viewsInitialized = false
|
||||
setupSharedElementTransitions()
|
||||
|
||||
return inflater.inflate(R.layout.fragment_home, container, false)
|
||||
// setupSharedElementTransitions()
|
||||
return DataBindingUtil.inflate<FragmentHomeBinding>(
|
||||
inflater, R.layout.fragment_home, container, false
|
||||
).let {
|
||||
binding = it
|
||||
it.root
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSharedElementTransitions() {
|
||||
val enterTransitionSet =
|
||||
TransitionInflater.from(mainActivity).inflateTransition(R.transition.transition_zec_sent).apply {
|
||||
duration = 3000L
|
||||
}.addListener(HomeTransitionListener())
|
||||
|
||||
this.sharedElementEnterTransition = enterTransitionSet
|
||||
this.sharedElementReturnTransition = enterTransitionSet
|
||||
TransitionInflater.from(mainActivity).inflateTransition(R.transition.transition_zec_sent).apply {
|
||||
duration = 3000L
|
||||
addListener(HomeTransitionListener())
|
||||
this@HomeFragment.sharedElementEnterTransition = this
|
||||
this@HomeFragment.sharedElementReturnTransition = this
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
// setActiveTransactionsShown(false)
|
||||
|
||||
|
||||
headerFullViews = arrayOf(text_balance_usd, text_balance_includes_info, text_balance_zec, image_zec_symbol_balance_shadow, image_zec_symbol_balance)
|
||||
headerEmptyViews = arrayOf(text_balance_zec_info, text_balance_zec_empty, image_zec_symbol_balance_shadow_empty, image_zec_symbol_balance_empty)
|
||||
|
||||
// toggling determines visibility. hide it all.
|
||||
headerFullViews.forEach { container_home_header.removeView(it) }
|
||||
headerEmptyViews.forEach { container_home_header.removeView(it) }
|
||||
group_empty_view_items.visibility = View.GONE
|
||||
group_full_view_items.visibility = View.GONE
|
||||
|
||||
image_logo.setOnClickListener {
|
||||
if (MainActivity.DEV_MODE) {
|
||||
mainActivity.navController.navigate(R.id.nav_send_fragment)
|
||||
// forceRedraw()
|
||||
// toggleViews(false)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
button_active_transaction_cancel.setOnClickListener {
|
||||
val transaction = button_active_transaction_cancel.tag as? ActiveSendTransaction
|
||||
if (transaction != null) {
|
||||
homePresenter.onCancelActiveTransaction(transaction)
|
||||
} else {
|
||||
Toaster.short("Error: unable to find transaction to cancel!")
|
||||
}
|
||||
}
|
||||
|
||||
refresh_layout.setOnRefreshListener {
|
||||
val fauxRefresh = Random.nextLong(750L..3000L)
|
||||
refresh_layout.postDelayed({
|
||||
refresh_layout.isRefreshing = false
|
||||
}, fauxRefresh)
|
||||
}
|
||||
|
||||
launch {
|
||||
Log.e("TWIG", "deciding whether to show first run")
|
||||
val extraDelay = measureTimeMillis {
|
||||
setFirstRunShown(mainActivity.synchronizer.isFirstRun() || mainActivity.synchronizer.isOutOfSync())
|
||||
}
|
||||
Log.e("TWIG", "done deciding whether to show first run in $extraDelay ms. Was that worth it? Or should we toggle a boolean in the application class?")
|
||||
}
|
||||
|
||||
header_active_transaction.visibility = View.GONE
|
||||
refresh_layout.setProgressViewEndTarget(false, (86f * resources.displayMetrics.density).toInt())
|
||||
initTemp()
|
||||
init()
|
||||
// launch {
|
||||
// Log.e("TWIG", "deciding whether to show first run")
|
||||
// val extraDelay = measureTimeMillis {
|
||||
// setFirstRunShown(mainActivity.synchronizer.isFirstRun() || mainActivity.synchronizer.isOutOfSync())
|
||||
// }
|
||||
// Log.e("TWIG", "done deciding whether to show first run in $extraDelay ms. Was that worth it? Or should we toggle a boolean in the application class?")
|
||||
// }
|
||||
}
|
||||
|
||||
private fun setFirstRunShown(isShown: Boolean) {
|
||||
container_first_run?.visibility = if (isShown) View.VISIBLE else View.GONE
|
||||
mainActivity.setDrawerLocked(isShown)
|
||||
sd_fab?.visibility = if (!isShown) View.VISIBLE else View.GONE
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
with(mainActivity) {
|
||||
setSupportActionBar(binding.includeHeader.homeToolbar)
|
||||
setupNavigation()
|
||||
supportActionBar?.setTitle(R.string.destination_title_home)
|
||||
}
|
||||
initFab()
|
||||
|
||||
homePresenter = HomePresenter(this, mainActivity.synchronizer)
|
||||
|
||||
binding.includeContent.recyclerTransactions.apply {
|
||||
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
|
||||
adapter = TransactionAdapter()
|
||||
addItemDecoration(AlternatingRowColorDecoration())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// val isEmpty = (recycler_transactions?.adapter?.itemCount ?: 0).let { it == 0 }
|
||||
// Log.e("TWIG-t", "Resuming and isEmpty == $isEmpty")
|
||||
// toggleViews(isEmpty)
|
||||
|
||||
launch {
|
||||
homePresenter.start()
|
||||
}
|
||||
|
@ -150,28 +120,7 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
override fun onPause() {
|
||||
super.onPause()
|
||||
homePresenter.stop()
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
(activity as MainActivity).let { mainActivity ->
|
||||
mainActivity.setSupportActionBar(home_toolbar)
|
||||
mainActivity.setupNavigation()
|
||||
mainActivity.supportActionBar?.setTitle(R.string.destination_title_home)
|
||||
}
|
||||
|
||||
homePresenter = HomePresenter(this, mainActivity.synchronizer)
|
||||
initFab(activity!!)
|
||||
|
||||
recycler_transactions.apply {
|
||||
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
|
||||
adapter = TransactionAdapter().also { transactionAdapter = it }
|
||||
addItemDecoration(AlternatingRowColorDecoration())
|
||||
|
||||
}
|
||||
// recycler_transactions.setOnClickListener {
|
||||
// mainActivity.navController.navigate(R.id.nav_history_fragment)
|
||||
// }
|
||||
binding.lottieZcashBadge.cancelAnimation()
|
||||
}
|
||||
|
||||
|
||||
|
@ -179,70 +128,109 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
// View API
|
||||
//
|
||||
|
||||
fun setContentViewShown(isShown: Boolean) {
|
||||
with(binding.includeContent) {
|
||||
groupEmptyViewItems.visibility = if (isShown) View.GONE else View.VISIBLE
|
||||
groupContentViewItems.visibility = if (isShown) View.VISIBLE else View.GONE
|
||||
}
|
||||
toggleViews(!isShown)
|
||||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
setRefreshAnimationPlaying(true).also { Log.e("TWIG-a", "refresh true from onRefresh") }
|
||||
|
||||
with(binding.includeContent.refreshLayout) {
|
||||
isRefreshing = false
|
||||
val fauxRefresh = Random.nextLong(750L..3000L)
|
||||
postDelayed({
|
||||
setRefreshAnimationPlaying(false).also { Log.e("TWIG-a", "refresh false from onRefresh") }
|
||||
}, fauxRefresh)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun setRefreshAnimationPlaying(isPlaying: Boolean) {
|
||||
Log.e("TWIG-a", "set refresh to: $isPlaying for $zcashLogoAnimation")
|
||||
if (isPlaying) {
|
||||
zcashLogoAnimation.start()
|
||||
} else {
|
||||
zcashLogoAnimation.stop()
|
||||
view?.postDelayed({
|
||||
zcashLogoAnimation.stop()
|
||||
}, 500L)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO: pull some of this logic into the presenter, particularly the part that deals with ZEC <-> USD price conversion
|
||||
override fun updateBalance(old: Long, new: Long) {
|
||||
//TODO: remove this kind of thing
|
||||
snackbar?.dismiss()
|
||||
|
||||
Log.e("TWIG-t", "updating balance from $old to $new")
|
||||
val zecValue = new/1e8
|
||||
swapEmptyViewsForBalance(zecValue)
|
||||
|
||||
// TODO: animate the change in value
|
||||
setZecValue(zecValue)
|
||||
setUsdValue(MainActivity.USD_PER_ZEC * zecValue)
|
||||
setUsdValue(SampleProperties.USD_PER_ZEC * zecValue)
|
||||
|
||||
onContentRefreshComplete(zecValue)
|
||||
}
|
||||
|
||||
override fun setTransactions(transactions: List<WalletTransaction>) {
|
||||
Log.e("TWIG-t", "submitList called with ${transactions.size} transactions")
|
||||
transactionAdapter.submitList(transactions)
|
||||
recycler_transactions.postDelayed({
|
||||
recycler_transactions.smoothScrollToPosition(0)
|
||||
}, 100L)
|
||||
if (transactions.isNotEmpty()) setFirstRunShown(false)
|
||||
with (binding.includeContent.recyclerTransactions) {
|
||||
(adapter as TransactionAdapter).submitList(transactions)
|
||||
postDelayed({
|
||||
smoothScrollToPosition(0)
|
||||
}, 100L)
|
||||
if (binding.includeFirstRun.visibility == View.VISIBLE) setFirstRunShown(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun showProgress(progress: Int) {
|
||||
Log.e("TWIG", "showing progress of $progress")
|
||||
if(progress >= 100) {
|
||||
view?.postDelayed({
|
||||
onInitialLoadComplete()
|
||||
}, 3000L)
|
||||
} else {
|
||||
setRefreshAnimationPlaying(true).also { Log.e("TWIG-a", "refresh true from showProgress") }
|
||||
binding.includeContent.textEmptyWalletMessage.setText(R.string.home_empty_wallet_updating)
|
||||
}
|
||||
// snackbar.showOk(view!!, "progress: $progress")
|
||||
// TODO: improve this with Lottie animation. but for now just use the empty view for downloading...
|
||||
// var hasEmptyViews = group_empty_view_items.visibility == View.VISIBLE
|
||||
// if(!viewsInitialized) toggleViews(true)
|
||||
//
|
||||
val message = if(progress >= 100) "Download complete! Processing blocks..." else "Downloading remaining blocks ($progress%)"
|
||||
// text_wallet_message.text = message
|
||||
|
||||
if (snackbar == null && progress <= 50) {
|
||||
snackbar = Snackbar.make(view!!, "$message", Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction("OK") {
|
||||
snackbar?.dismiss()
|
||||
}
|
||||
snackbar?.show()
|
||||
} else {
|
||||
snackbar?.setText(message)
|
||||
if(snackbar?.isShownOrQueued != true) snackbar?.show()
|
||||
}
|
||||
// val message = if(progress >= 100) "Download complete! Processing blocks..." else "Downloading remaining blocks ($progress%)"
|
||||
//// text_wallet_message.text = message
|
||||
//
|
||||
// if (snackbar == null && progress <= 50) {
|
||||
// snackbar = Snackbar.make(view!!, "$message", Snackbar.LENGTH_INDEFINITE)
|
||||
// .setAction("OK") {
|
||||
// snackbar?.dismiss()
|
||||
// }
|
||||
// snackbar?.show()
|
||||
// } else {
|
||||
// snackbar?.setText(message)
|
||||
// if(snackbar?.isShownOrQueued != true) snackbar?.show()
|
||||
// }
|
||||
}
|
||||
|
||||
fun showOkSnack(message: String) {
|
||||
if (snackbar == null) {
|
||||
snackbar = Snackbar.make(view!!, "$message", Snackbar.LENGTH_INDEFINITE).setAction("OK") {
|
||||
snackbar?.dismiss()
|
||||
snackbar = null
|
||||
}
|
||||
snackbar?.show()
|
||||
} else {
|
||||
snackbar?.setText(message)
|
||||
if (snackbar?.isShownOrQueued != true) snackbar?.show()
|
||||
private fun onInitialLoadComplete() {
|
||||
val isEmpty = (binding.includeContent.recyclerTransactions?.adapter?.itemCount ?: 0).let { it == 0 }
|
||||
Log.e("TWIG-t", "onInitialLoadComplete and isEmpty == $isEmpty")
|
||||
setContentViewShown(!isEmpty)
|
||||
if (isEmpty) {
|
||||
binding.includeContent.textEmptyWalletMessage.setText(R.string.home_empty_wallet)
|
||||
}
|
||||
setRefreshAnimationPlaying(false).also { Log.e("TWIG-a", "refresh false from onInitialLoadComplete") }
|
||||
}
|
||||
|
||||
|
||||
override fun setActiveTransactions(activeTransactionMap: Map<ActiveTransaction, TransactionState>) {
|
||||
if (activeTransactionMap.isEmpty()) {
|
||||
setActiveTransactionsShown(false)
|
||||
return
|
||||
}
|
||||
|
||||
setActiveTransactionsShown(true)
|
||||
val transactions = activeTransactionMap.entries.toTypedArray()
|
||||
// primary is the last one that was inserted
|
||||
val primaryEntry = transactions[transactions.size - 1]
|
||||
|
@ -251,16 +239,17 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
}
|
||||
|
||||
override fun onCancelledTooLate() {
|
||||
showOkSnack("Oops! It was too late to cancel!")
|
||||
snackbar = snackbar.showOk(view!!, "Oops! It was too late to cancel!")
|
||||
}
|
||||
|
||||
private fun updatePrimaryTransaction(transaction: ActiveTransaction, transactionState: TransactionState) {
|
||||
setActiveTransactionsShown(true)
|
||||
Log.e("TWIG", "setting transaction state to ${transactionState::class.simpleName}")
|
||||
var title = "Active Transaction"
|
||||
var subtitle = "Processing..."
|
||||
when (transactionState) {
|
||||
TransactionState.Creating -> {
|
||||
header_active_transaction.visibility = View.VISIBLE
|
||||
binding.includeContent.headerActiveTransaction.visibility = View.VISIBLE
|
||||
title = "Preparing ${transaction.value.toZec(3)} ZEC"
|
||||
subtitle = "to ${(transaction as ActiveSendTransaction).toAddress}"
|
||||
setTransactionActive(transaction, true)
|
||||
|
@ -268,48 +257,48 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
TransactionState.SendingToNetwork -> {
|
||||
title = "Sending Transaction"
|
||||
subtitle = "to ${(transaction as ActiveSendTransaction).toAddress}"
|
||||
text_active_transaction_value.text = "${transaction.value/1000L}"
|
||||
text_active_transaction_value.visibility = View.VISIBLE
|
||||
button_active_transaction_cancel.visibility = View.GONE
|
||||
binding.includeContent.textActiveTransactionValue.text = "${transaction.value/1000L}"
|
||||
binding.includeContent.textActiveTransactionValue.visibility = View.VISIBLE
|
||||
binding.includeContent.buttonActiveTransactionCancel.visibility = View.GONE
|
||||
}
|
||||
is TransactionState.Failure -> {
|
||||
lottie_active_transaction.setAnimation(R.raw.lottie_send_failure)
|
||||
lottie_active_transaction.playAnimation()
|
||||
binding.includeContent.lottieActiveTransaction.setAnimation(R.raw.lottie_send_failure)
|
||||
binding.includeContent.lottieActiveTransaction.playAnimation()
|
||||
title = "Failed"
|
||||
subtitle = when(transactionState.failedStep) {
|
||||
TransactionState.Creating -> "Failed to create transaction"
|
||||
TransactionState.SendingToNetwork -> "Failed to submit transaction to the network"
|
||||
else -> "Unrecoginzed error"
|
||||
}
|
||||
button_active_transaction_cancel.visibility = View.GONE
|
||||
text_active_transaction_value.visibility = View.GONE
|
||||
binding.includeContent.buttonActiveTransactionCancel.visibility = View.GONE
|
||||
binding.includeContent.textActiveTransactionValue.visibility = View.GONE
|
||||
setTransactionActive(transaction, false)
|
||||
setActiveTransactionsShown(false, 10000L)
|
||||
}
|
||||
is TransactionState.AwaitingConfirmations -> {
|
||||
if (transactionState.confirmationCount < 1) {
|
||||
lottie_active_transaction.setAnimation(R.raw.lottie_send_success)
|
||||
lottie_active_transaction.playAnimation()
|
||||
binding.includeContent.lottieActiveTransaction.setAnimation(R.raw.lottie_send_success)
|
||||
binding.includeContent.lottieActiveTransaction.playAnimation()
|
||||
title = "ZEC Sent"
|
||||
subtitle = "Today at 4:46pm"
|
||||
text_active_transaction_value.text = transaction.value.toZec(3).toString()
|
||||
text_active_transaction_value.visibility = View.VISIBLE
|
||||
button_active_transaction_cancel.visibility = View.GONE
|
||||
subtitle = "Today at 2:11pm"
|
||||
binding.includeContent.textActiveTransactionValue.text = transaction.value.toZec(3).toString()
|
||||
binding.includeContent.textActiveTransactionValue.visibility = View.VISIBLE
|
||||
binding.includeContent.buttonActiveTransactionCancel.visibility = View.GONE
|
||||
} else {
|
||||
// play confirmation counting animation
|
||||
title = "Confirmation Received"
|
||||
subtitle = "Today at 2:12pm"
|
||||
// take it out of the list in a bit and skip counting confirmation animation for now (i.e. one is enough)
|
||||
setActiveTransactionsShown(false, 3000L)
|
||||
}
|
||||
}
|
||||
is TransactionState.Cancelled -> {
|
||||
title = text_active_transaction_title.text.toString()
|
||||
subtitle = text_active_transaction_subtitle.text.toString()
|
||||
title = binding.includeContent.textActiveTransactionTitle.text.toString()
|
||||
subtitle = binding.includeContent.textActiveTransactionSubtitle.text.toString()
|
||||
setTransactionActive(transaction, false)
|
||||
}
|
||||
}
|
||||
text_active_transaction_title.text = title
|
||||
text_active_transaction_subtitle.text = subtitle
|
||||
}
|
||||
|
||||
private fun setActiveTransactionsShown(isShown: Boolean) {
|
||||
header_active_transaction.visibility = if (isShown) View.VISIBLE else View.GONE
|
||||
binding.includeContent.textActiveTransactionTitle.text = title
|
||||
binding.includeContent.textActiveTransactionSubtitle.text = subtitle
|
||||
}
|
||||
|
||||
|
||||
|
@ -317,25 +306,96 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
// Private View API
|
||||
//
|
||||
|
||||
private fun setActiveTransactionsShown(isShown: Boolean, delay: Long = 0L) {
|
||||
Log.e("TWIG-a", "setActiveTransactionsShown: $isShown")
|
||||
binding.includeContent.headerActiveTransaction.postDelayed({
|
||||
binding.includeContent.groupActiveTransactionItems.visibility = if (isShown) View.VISIBLE else View.GONE
|
||||
}, delay)
|
||||
}
|
||||
|
||||
private fun setFirstRunShown(isShown: Boolean) {
|
||||
binding.includeFirstRun.visibility = if (isShown) View.VISIBLE else View.GONE
|
||||
mainActivity.setDrawerLocked(isShown)
|
||||
binding.sdFab.visibility = if (!isShown) View.VISIBLE else View.GONE
|
||||
binding.lottieZcashBadge.visibility = if(!isShown) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Fab button and all its action items
|
||||
*
|
||||
* @param activity a helper parameter that forces this method to be called after the activity is created and not null
|
||||
* General initialization called during onViewCreated. Mostly responsible for applying the default empty state of
|
||||
* the view, before any data or information is known.
|
||||
*/
|
||||
private fun initFab(activity: Activity) {
|
||||
val speedDial = sd_fab
|
||||
val nav = (activity as MainActivity).navController
|
||||
private fun init() {
|
||||
zcashLogoAnimation = LottieLooper(binding.lottieZcashBadge, 20..47, 69)
|
||||
binding.includeContent.buttonActiveTransactionCancel.setOnClickListener {
|
||||
val transaction = it.tag as? ActiveSendTransaction
|
||||
if (transaction != null) {
|
||||
homePresenter.onCancelActiveTransaction(transaction)
|
||||
} else {
|
||||
Toaster.short("Error: unable to find transaction to cancel!")
|
||||
}
|
||||
}
|
||||
|
||||
binding.includeContent.refreshLayout.setProgressViewEndTarget(false, (38f * resources.displayMetrics.density).toInt())
|
||||
|
||||
with(binding.includeContent.refreshLayout) {
|
||||
setOnRefreshListener(this@HomeFragment)
|
||||
setColorSchemeColors(R.color.zcashBlack.toAppColor())
|
||||
setProgressBackgroundColorSchemeColor(R.color.zcashYellow.toAppColor())
|
||||
}
|
||||
|
||||
// hide content
|
||||
setActiveTransactionsShown(false)
|
||||
setContentViewShown(false)
|
||||
binding.includeContent.textEmptyWalletMessage.setText(R.string.home_empty_wallet_updating)
|
||||
setRefreshAnimationPlaying(true).also { Log.e("TWIG-a", "refresh true from init") }
|
||||
}
|
||||
|
||||
// initialize the stuff that is temporary and needs to go ASAP
|
||||
private fun initTemp() {
|
||||
|
||||
with(binding.includeHeader) {
|
||||
headerFullViews = arrayOf(textBalanceUsd, textBalanceIncludesInfo, textBalanceZec, imageZecSymbolBalanceShadow, imageZecSymbolBalance)
|
||||
headerEmptyViews = arrayOf(textBalanceZecInfo, textBalanceZecEmpty, imageZecSymbolBalanceShadowEmpty, imageZecSymbolBalanceEmpty)
|
||||
headerFullViews.forEach { containerHomeHeader.removeView(it) }
|
||||
headerEmptyViews.forEach { containerHomeHeader.removeView(it) }
|
||||
binding.includeHeader.containerHomeHeader.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
// toggling determines visibility. hide it all.
|
||||
binding.includeContent.groupEmptyViewItems.visibility = View.GONE
|
||||
binding.includeContent.groupContentViewItems.visibility = View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Fab button and all its action items. Should be called during onActivityCreated.
|
||||
*/
|
||||
private fun initFab() {
|
||||
val speedDial = binding.sdFab
|
||||
val nav = mainActivity.navController
|
||||
|
||||
HomeFab.values().forEach {
|
||||
speedDial.addActionItem(it.createItem())
|
||||
}
|
||||
|
||||
speedDial.setOnActionSelectedListener { item ->
|
||||
HomeFab.fromId(item.id)?.destination?.apply { nav.navigate(this) }
|
||||
if (item.id == R.id.fab_request) {
|
||||
Toaster.short("off!")
|
||||
setActiveTransactionsShown(false)
|
||||
// setRefreshAnimationPlaying(false)
|
||||
} else if (item.id == R.id.fab_receive) {
|
||||
Toaster.short("on!")
|
||||
setActiveTransactionsShown(true)
|
||||
// setRefreshAnimationPlaying(true)
|
||||
} else {
|
||||
HomeFab.fromId(item.id)?.destination?.apply { nav.navigate(this) }
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for creating fablets--those little buttons that pop up when the fab is tapped.
|
||||
*/
|
||||
private val createItem: HomeFab.() -> SpeedDialActionItem = {
|
||||
SpeedDialActionItem.Builder(id, icon)
|
||||
.setFabBackgroundColor(bgColor.toAppColor())
|
||||
|
@ -352,11 +412,13 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
val textSpan = SpannableString(valueString)
|
||||
textSpan.setSpan(TopAlignedSpan(), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
textSpan.setSpan(TopAlignedSpan(), valueString.length - 3, valueString.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
text_balance_usd.text = textSpan
|
||||
binding.includeHeader.textBalanceUsd.text = textSpan
|
||||
}
|
||||
|
||||
private fun setZecValue(value: Double) {
|
||||
text_balance_zec.text = if(value == 0.0) "0" else String.format("%.3f",value)
|
||||
binding.includeHeader.textBalanceZec.text = if(value == 0.0) "0" else String.format("%.3f",value)
|
||||
|
||||
|
||||
// // bugfix: there is a bug in motionlayout that causes text to flicker as it is resized because the last character doesn't fit. Padding both sides with a thin space works around this bug.
|
||||
// val hairSpace = "\u200A"
|
||||
// val adjustedValue = "$hairSpace$valueString$hairSpace"
|
||||
|
@ -364,34 +426,38 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
}
|
||||
|
||||
/**
|
||||
* Called whenever the content has been refreshed on the screen. When it is time to show and hide things.
|
||||
* If the balance goes to zero, the wallet is now empty so show the empty view.
|
||||
* If the balance changes from zero, the wallet is no longer empty so hide the empty view.
|
||||
* But don't do either of these things if the situation has not changed.
|
||||
*/
|
||||
private fun swapEmptyViewsForBalance(value: Double) {
|
||||
private fun onContentRefreshComplete(value: Double) {
|
||||
val isEmpty = value <= 0.0
|
||||
// wasEmpty isn't enough info. it must be considered along with whether these views were ever initialized
|
||||
val wasEmpty = group_empty_view_items.visibility == View.VISIBLE
|
||||
val wasEmpty = binding.includeContent.groupEmptyViewItems.visibility == View.VISIBLE
|
||||
// situation has changed when we weren't initialized but now we have a balance or emptiness has changed
|
||||
val situationHasChanged = !viewsInitialized || (isEmpty != wasEmpty)
|
||||
|
||||
Log.e("TWIG-t", "updateEmptyViews called with value: $value initialized: $viewsInitialized isEmpty: $isEmpty wasEmpty: $wasEmpty")
|
||||
if (situationHasChanged) {
|
||||
Log.e("TWIG-t", "The situation has changed! toggling views!")
|
||||
toggleViews(isEmpty)
|
||||
setContentViewShown(!isEmpty)
|
||||
if (!isEmpty) setFirstRunShown(false)
|
||||
}
|
||||
|
||||
setRefreshAnimationPlaying(false).also { Log.e("TWIG-a", "refresh false from onContentRefreshComplete") }
|
||||
binding.includeHeader.containerHomeHeader.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun onActiveTransactionTransitionStart() {
|
||||
button_active_transaction_cancel.visibility = View.INVISIBLE
|
||||
binding.includeContent.buttonActiveTransactionCancel.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
private fun onActiveTransactionTransitionEnd() {
|
||||
// TODO: investigate if this fix is still required after getting transition animation working again
|
||||
// fixes a bug where the translation gets lost, during animation. As a nice side effect, visually, it makes the view appear to settle in to position
|
||||
header_active_transaction.translationZ = 10.0f
|
||||
button_active_transaction_cancel.apply {
|
||||
binding.includeContent.headerActiveTransaction.translationZ = 10.0f
|
||||
binding.includeContent.buttonActiveTransactionCancel.apply {
|
||||
postDelayed({text = "cancel"}, 50L)
|
||||
visibility = View.VISIBLE
|
||||
}
|
||||
|
@ -400,38 +466,27 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
private fun setTransactionActive(transaction: ActiveTransaction, isActive: Boolean) {
|
||||
// TODO: get view for transaction, mostly likely keep a sparse array of these or something
|
||||
if (isActive) {
|
||||
button_active_transaction_cancel.setText(R.string.cancel)
|
||||
button_active_transaction_cancel.isEnabled = true
|
||||
button_active_transaction_cancel.tag = transaction
|
||||
header_active_transaction.animate().apply {
|
||||
binding.includeContent.buttonActiveTransactionCancel.setText(R.string.cancel)
|
||||
binding.includeContent.buttonActiveTransactionCancel.isEnabled = true
|
||||
binding.includeContent.buttonActiveTransactionCancel.tag = transaction
|
||||
binding.includeContent.headerActiveTransaction.animate().apply {
|
||||
translationZ(10f)
|
||||
duration = 200L
|
||||
interpolator = DecelerateInterpolator()
|
||||
}
|
||||
} else {
|
||||
button_active_transaction_cancel.setText(R.string.cancelled)
|
||||
button_active_transaction_cancel.isEnabled = false
|
||||
button_active_transaction_cancel.tag = null
|
||||
header_active_transaction.animate().apply {
|
||||
binding.includeContent.buttonActiveTransactionCancel.setText(R.string.cancelled)
|
||||
binding.includeContent.buttonActiveTransactionCancel.isEnabled = false
|
||||
binding.includeContent.buttonActiveTransactionCancel.tag = null
|
||||
binding.includeContent.headerActiveTransaction.animate().apply {
|
||||
translationZ(2f)
|
||||
duration = 300L
|
||||
interpolator = AccelerateInterpolator()
|
||||
}
|
||||
lottie_active_transaction.cancelAnimation()
|
||||
binding.includeContent.lottieActiveTransaction.cancelAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
inner class HomeTransitionListener : Transition.TransitionListener {
|
||||
override fun onTransitionStart(transition: Transition) {
|
||||
onActiveTransactionTransitionStart()
|
||||
}
|
||||
override fun onTransitionEnd(transition: Transition) {
|
||||
onActiveTransactionTransitionEnd()
|
||||
}
|
||||
override fun onTransitionResume(transition: Transition){}
|
||||
override fun onTransitionPause(transition: Transition){}
|
||||
override fun onTransitionCancel(transition: Transition) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the basic properties of each FAB button for use while initializing the FAB
|
||||
|
@ -470,23 +525,23 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
fun fromId(id: Int): HomeFab? = values().firstOrNull { it.id == id }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
// TODO: Delete these test functions
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//// ---------------------------------------------------------------------------------------------------------------------
|
||||
//// TODO: Delete these test functions
|
||||
//// ---------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
var empty = false
|
||||
val delay = 50L
|
||||
lateinit var headerEmptyViews: Array<View>
|
||||
lateinit var headerFullViews: Array<View>
|
||||
|
||||
fun shrink(): Double {
|
||||
return text_balance_zec.text.toString().trim().toDouble() - Random.nextDouble(5.0)
|
||||
return binding.includeHeader.textBalanceZec.text.toString().trim().toDouble() - Random.nextDouble(5.0)
|
||||
}
|
||||
fun grow(): Double {
|
||||
return text_balance_zec.text.toString().trim().toDouble() + Random.nextDouble(5.0)
|
||||
return binding.includeHeader.textBalanceZec.text.toString().trim().toDouble() + Random.nextDouble(5.0)
|
||||
}
|
||||
fun reduceValue() {
|
||||
shrink().let {
|
||||
|
@ -512,36 +567,70 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
}
|
||||
fun forceRedraw() {
|
||||
view?.postDelayed({
|
||||
container_home_header.progress = container_home_header.progress - 0.1f
|
||||
binding.includeHeader.containerHomeHeader.progress = binding.includeHeader.containerHomeHeader.progress - 0.1f
|
||||
}, delay * 2)
|
||||
}
|
||||
internal fun toggle(isEmpty: Boolean) {
|
||||
toggleValues(isEmpty)
|
||||
}
|
||||
|
||||
// TODO: get rid of all of this and consider two different fragments for the header, instead
|
||||
internal fun toggleViews(isEmpty: Boolean) {
|
||||
Log.e("TWIG-t", "toggling views to isEmpty == $isEmpty")
|
||||
var action: () -> Unit
|
||||
if (isEmpty) {
|
||||
action = {
|
||||
group_empty_view_items.visibility = View.VISIBLE
|
||||
group_full_view_items.visibility = View.GONE
|
||||
headerFullViews.forEach { container_home_header.removeView(it) }
|
||||
binding.includeContent.groupEmptyViewItems.visibility = View.VISIBLE
|
||||
binding.includeContent.groupContentViewItems.visibility = View.GONE
|
||||
headerFullViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
|
||||
headerEmptyViews.forEach {
|
||||
tryIgnore {
|
||||
container_home_header.addView(it)
|
||||
binding.includeHeader.containerHomeHeader.addView(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
action = {
|
||||
group_empty_view_items.visibility = View.GONE
|
||||
group_full_view_items.visibility = View.VISIBLE
|
||||
headerEmptyViews.forEach { container_home_header.removeView(it) }
|
||||
binding.includeContent.groupEmptyViewItems.visibility = View.GONE
|
||||
binding.includeContent.groupContentViewItems.visibility = View.VISIBLE
|
||||
headerEmptyViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
|
||||
headerFullViews.forEach {
|
||||
tryIgnore {
|
||||
container_home_header.addView(it)
|
||||
binding.includeHeader.containerHomeHeader.addView(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
view?.postDelayed({
|
||||
binding.includeHeader.containerHomeHeader.visibility = View.VISIBLE
|
||||
action()
|
||||
viewsInitialized = true
|
||||
}, delay)
|
||||
// TODO: the motion layout does not begin in the right state for some reason. Debug this later.
|
||||
view?.postDelayed(::forceRedraw, delay * 2)
|
||||
}
|
||||
|
||||
// TODO: get rid of all of this and consider two different fragments for the header, instead
|
||||
internal fun toggleViews2(isEmpty: Boolean) {
|
||||
var action: () -> Unit
|
||||
if (isEmpty) {
|
||||
action = {
|
||||
// group_empty_view_items.visibility = View.VISIBLE
|
||||
// group_full_view_items.visibility = View.GONE
|
||||
headerFullViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
|
||||
headerEmptyViews.forEach {
|
||||
tryIgnore {
|
||||
binding.includeHeader.containerHomeHeader.addView(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
action = {
|
||||
// group_empty_view_items.visibility = View.GONE
|
||||
// group_full_view_items.visibility = View.VISIBLE
|
||||
headerEmptyViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
|
||||
headerFullViews.forEach {
|
||||
tryIgnore {
|
||||
binding.includeHeader.containerHomeHeader.addView(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -562,10 +651,25 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
|||
increaseValue(Random.nextDouble(20.0, 100.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inner class HomeTransitionListener : Transition.TransitionListener {
|
||||
override fun onTransitionStart(transition: Transition) {
|
||||
}
|
||||
|
||||
override fun onTransitionEnd(transition: Transition) {
|
||||
}
|
||||
|
||||
override fun onTransitionResume(transition: Transition) {}
|
||||
override fun onTransitionPause(transition: Transition) {}
|
||||
override fun onTransitionCancel(transition: Transition) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Module
|
||||
abstract class HomeFragmentModule {
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributeHomeFragment(): HomeFragment
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package cash.z.android.wallet.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import cash.z.android.wallet.R
|
||||
import cash.z.android.wallet.databinding.IncludeHomeHeaderBinding
|
||||
|
||||
class HomeHeaderEmptyFragment : Fragment() {
|
||||
private lateinit var binding: IncludeHomeHeaderBinding
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, parent: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return DataBindingUtil
|
||||
.inflate<IncludeHomeHeaderBinding>(inflater, R.layout.include_home_header, parent, false).let {
|
||||
binding = it
|
||||
it.root
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.text.toSpannable
|
||||
import androidx.databinding.DataBindingUtil
|
||||
|
@ -20,11 +19,12 @@ import cash.z.android.wallet.databinding.FragmentSendBinding
|
|||
import cash.z.android.wallet.extention.afterTextChanged
|
||||
import cash.z.android.wallet.extention.toAppColor
|
||||
import cash.z.android.wallet.extention.tryIgnore
|
||||
import cash.z.android.wallet.sample.SampleProperties
|
||||
import cash.z.android.wallet.sample.SampleProperties.DEV_MODE
|
||||
import cash.z.android.wallet.ui.activity.MainActivity
|
||||
import cash.z.android.wallet.ui.presenter.SendPresenter
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.DecimalFormat
|
||||
|
||||
|
@ -55,7 +55,7 @@ class SendFragment : BaseFragment(), SendPresenter.SendView {
|
|||
//
|
||||
// this.allowReturnTransitionOverlap = false
|
||||
// allowEnterTransitionOverlap = false
|
||||
0
|
||||
|
||||
return DataBindingUtil.inflate<FragmentSendBinding>(
|
||||
inflater, R.layout.fragment_send, container, false
|
||||
).let {
|
||||
|
@ -85,9 +85,9 @@ class SendFragment : BaseFragment(), SendPresenter.SendView {
|
|||
tryIgnore {
|
||||
val value = binding.textValueHeader.text.toString().toDouble()
|
||||
binding.textValueSubheader.text = if (zecSelected) {
|
||||
usdFormatter.format(value * MainActivity.USD_PER_ZEC)
|
||||
usdFormatter.format(value * SampleProperties.USD_PER_ZEC)
|
||||
} else {
|
||||
zecFormatter.format(value / MainActivity.USD_PER_ZEC)
|
||||
zecFormatter.format(value / SampleProperties.USD_PER_ZEC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class SendFragment : BaseFragment(), SendPresenter.SendView {
|
|||
hideSendDialog()
|
||||
}
|
||||
binding.dialogSubmitButton.setOnClickListener {
|
||||
if (MainActivity.DEV_MODE) submit() else onSendZec()
|
||||
if (DEV_MODE) submit() else onSendZec()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ class SendFragment : BaseFragment(), SendPresenter.SendView {
|
|||
launch {
|
||||
sendPresenter.start()
|
||||
}
|
||||
if(MainActivity.DEV_MODE) showSendDialog()
|
||||
if(DEV_MODE) showSendDialog()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
|
@ -131,13 +131,19 @@ class SendFragment : BaseFragment(), SendPresenter.SendView {
|
|||
}
|
||||
|
||||
override fun submit() {
|
||||
mainActivity.navController.navigate(R.id.nav_home_fragment,
|
||||
null,
|
||||
null,
|
||||
FragmentNavigatorExtras(binding.dialogTextTitle to "transition_active_transaction_title"))
|
||||
submitNoAnimations()
|
||||
}
|
||||
|
||||
fun submitOld() {
|
||||
private fun submitNoAnimations() {
|
||||
mainActivity.navController.navigate(
|
||||
R.id.nav_home_fragment,
|
||||
null,
|
||||
null,
|
||||
FragmentNavigatorExtras(binding.dialogTextTitle to "transition_active_transaction_title")
|
||||
)
|
||||
}
|
||||
|
||||
fun submitWithSharedElements() {
|
||||
var extras = with(binding) {
|
||||
listOf(dialogSendBackground, dialogSendContents, dialogTextTitle, dialogTextAddress)
|
||||
.map{ it to it.transitionName }
|
||||
|
@ -171,7 +177,7 @@ class SendFragment : BaseFragment(), SendPresenter.SendView {
|
|||
|
||||
override fun updateBalance(old: Long, new: Long) {
|
||||
val zecBalance = new / 100000000.0
|
||||
val usdBalance = zecBalance * MainActivity.USD_PER_ZEC
|
||||
val usdBalance = zecBalance * SampleProperties.USD_PER_ZEC
|
||||
val availableZecFormatter = DecimalFormat("#.########")
|
||||
// TODO: use a formatted string resource here
|
||||
val availableTextSpan = "${availableZecFormatter.format(zecBalance)} ZEC Available".toSpannable()
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package cash.z.android.wallet.ui.util
|
||||
|
||||
import android.animation.Animator
|
||||
import cash.z.android.wallet.extention.Toaster
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.airbnb.lottie.LottieDrawable
|
||||
|
||||
/**
|
||||
* Utility to help with looping a lottie animation over a particular range. It will start the animation and play it up
|
||||
* to the end of the range and then set it to loop over the range and, once stopped, it will proceed from the current
|
||||
* frame to the end of the animation. Visually: BEGIN...LOOP...LOOP...LOOP...END
|
||||
*/
|
||||
class LottieLooper(private val lottie: LottieAnimationView, private val loopRange: IntRange, private val lastFrame: Int = Int.MAX_VALUE) :
|
||||
Animator.AnimatorListener {
|
||||
|
||||
var isPlaying = false
|
||||
|
||||
fun start() {
|
||||
if (isPlaying) return
|
||||
with(lottie) {
|
||||
setMinAndMaxFrame(1, loopRange.last)
|
||||
repeatCount = 0
|
||||
addAnimatorListener(this@LottieLooper)
|
||||
playAnimation()
|
||||
}
|
||||
isPlaying = true
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
with(lottie) {
|
||||
setMinAndMaxFrame(lottie.frame, lastFrame)
|
||||
repeatCount = 0
|
||||
// we don't want to just cancel the animation. We want it to finish it's final frames but the moment it is
|
||||
// done, we need it to freeze on that final frame and then die
|
||||
addAnimatorListener(LottieAssassin())
|
||||
}
|
||||
isPlaying = false
|
||||
}
|
||||
|
||||
override fun onAnimationRepeat(animation: Animator?) {
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
with(lottie) {
|
||||
removeAllAnimatorListeners()
|
||||
setMinAndMaxFrame(loopRange.first, loopRange.last)
|
||||
repeatCount = LottieDrawable.INFINITE
|
||||
playAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator?) {
|
||||
}
|
||||
|
||||
override fun onAnimationStart(animation: Animator?) {
|
||||
}
|
||||
|
||||
/** I have one job: kill lottie */
|
||||
inner class LottieAssassin : Animator.AnimatorListener {
|
||||
override fun onAnimationRepeat(animation: Animator?) {
|
||||
finishingMove()
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
finishingMove()
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator?) {
|
||||
finishingMove()
|
||||
}
|
||||
|
||||
override fun onAnimationStart(animation: Animator?) {
|
||||
finishingMove()
|
||||
}
|
||||
|
||||
/** Agressively force it to freeze on the lastframe */
|
||||
private fun finishingMove() {
|
||||
lottie.pauseAnimation()
|
||||
lottie.setMinAndMaxFrame(lastFrame, lastFrame)
|
||||
lottie.progress = 1.0f
|
||||
// wait around a bit to see if there's any movement, then quietly make my getaway
|
||||
lottie.postDelayed({
|
||||
lottie.removeAnimatorListener(this)
|
||||
lottie.setMinAndMaxFrame(1, lastFrame)
|
||||
}, 500L)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false">
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/home_app_bar"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/home_app_bar_expanded_height"
|
||||
android:theme="@style/ZcashTheme.AppBarOverlay">
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false">
|
||||
|
||||
<include layout="@layout/include_home_header" />
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/home_app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/home_app_bar_expanded_height"
|
||||
android:theme="@style/ZcashTheme.AppBarOverlay">
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<include
|
||||
android:id="@+id/include_header"
|
||||
layout="@layout/include_home_header" />
|
||||
|
||||
<include layout="@layout/include_home_content" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<!-- FAB -->
|
||||
<com.leinardi.android.speeddial.SpeedDialView
|
||||
android:id="@+id/sd_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
app:sdMainFabClosedBackgroundColor="@color/fab_closed_color"
|
||||
app:sdMainFabClosedSrc="@drawable/ic_add_white_24dp"
|
||||
app:sdMainFabOpenedBackgroundColor="@color/fab_open_color" />
|
||||
<include
|
||||
android:id="@+id/include_content"
|
||||
layout="@layout/include_home_content" />
|
||||
|
||||
<!-- Zcash badge -->
|
||||
<ImageView
|
||||
android:id="@+id/image_logo"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:elevation="6dp"
|
||||
app:layout_anchor="@id/home_app_bar"
|
||||
app:layout_anchorGravity="bottom|center"
|
||||
app:srcCompat="@drawable/ic_zcashlogo_badge" />
|
||||
<!-- FAB -->
|
||||
<com.leinardi.android.speeddial.SpeedDialView
|
||||
android:id="@+id/sd_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
app:sdMainFabClosedBackgroundColor="@color/fab_closed_color"
|
||||
app:sdMainFabClosedSrc="@drawable/ic_add_white_24dp"
|
||||
app:sdMainFabOpenedBackgroundColor="@color/fab_open_color" />
|
||||
|
||||
<include layout="@layout/activity_main_first_run"/>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
<!-- Zcash badge - refresh animation -->
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottie_zcash_badge"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:elevation="6dp"
|
||||
app:layout_anchor="@id/home_app_bar"
|
||||
app:layout_anchorGravity="bottom|center"
|
||||
app:lottie_autoPlay="false"
|
||||
app:lottie_loop="false"
|
||||
app:lottie_rawRes="@raw/lottie_zcash_badge_refresh_whitebg" />
|
||||
|
||||
<include
|
||||
android:id="@+id/include_first_run"
|
||||
layout="@layout/activity_main_first_run" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</layout>
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2018 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.
|
||||
-->
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<cash.z.android.wallet.ui.view.CollapsingMotionToolbar
|
||||
android:id="@+id/fragment_container_home_header_empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:layoutDescription="@xml/scene_fragment_home_header_empty"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"
|
||||
tools:showIn="@layout/fragment_home">
|
||||
|
||||
<!-- balance: empty -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:shadowColor="@color/text_shadow"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="8"
|
||||
android:shadowRadius="24"
|
||||
android:text="0"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="60dp" />
|
||||
|
||||
</cash.z.android.wallet.ui.view.CollapsingMotionToolbar>
|
||||
</layout>
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2018 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.
|
||||
-->
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<cash.z.android.wallet.ui.view.CollapsingMotionToolbar
|
||||
android:id="@+id/fragment_container_home_header_full"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:layoutDescription="@xml/scene_fragment_home_header_full"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"
|
||||
tools:showIn="@layout/fragment_home">
|
||||
|
||||
|
||||
<!-- balance -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:shadowColor="@color/text_shadow"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="8"
|
||||
android:shadowRadius="24"
|
||||
tools:text="35.021"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="60dp" />
|
||||
|
||||
</cash.z.android.wallet.ui.view.CollapsingMotionToolbar>
|
||||
</layout>
|
|
@ -1,181 +1,206 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/fragment_home_background"
|
||||
android:fillViewport="true"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/refresh_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/fragment_home_background"
|
||||
android:fillViewport="true"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/content_home"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="30dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:transitionName="@string/transition_active_transaction_background">
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/refresh_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Active Transaction - primary -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/header_active_transaction"
|
||||
android:id="@+id/content_home"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:background="@drawable/background_rounded_corners_slight"
|
||||
android:clipToPadding="false"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingTop="30dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:transitionName="@string/transition_active_transaction_card"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
android:transitionName="@string/transition_active_transaction_background">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottie_active_transaction"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
<!-- Label: Current Activity -->
|
||||
<TextView
|
||||
android:id="@+id/text_active_transaction_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/home_current_transaction_label"
|
||||
android:textColor="@color/text_dark"
|
||||
android:textSize="@dimen/text_size_body_2"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="false"
|
||||
app:lottie_rawRes="@raw/lottie_send_common" />
|
||||
tools:visibility="visible" />
|
||||
|
||||
<!-- Active Transaction - primary -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/header_active_transaction"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="@drawable/background_rounded_corners_slight"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:transitionName="@string/transition_active_transaction_card"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_active_transaction_header"
|
||||
tools:visibility="visible">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottie_active_transaction"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="false"
|
||||
app:lottie_rawRes="@raw/lottie_send_common" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_active_transaction_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:textSize="@dimen/text_size_body_1"
|
||||
android:textStyle="bold"
|
||||
android:transitionName="@string/transition_active_transaction_title"
|
||||
app:layout_constraintBottom_toTopOf="@id/text_active_transaction_subtitle"
|
||||
app:layout_constraintStart_toEndOf="@id/lottie_active_transaction"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
tools:text="Preparing 1.01 ZEC" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_active_transaction_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="to zsapling...123456789"
|
||||
android:textSize="@dimen/text_size_caption"
|
||||
android:transitionName="@string/transition_active_transaction_address"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/text_active_transaction_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_active_transaction_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_active_transaction_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:textColor="@color/text_dark_dimmed"
|
||||
android:textSize="@dimen/text_size_h5"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_active_transaction_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:text="cancel"
|
||||
android:textColor="@color/selector_red_button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- Label: Past Activity -->
|
||||
<TextView
|
||||
android:id="@+id/text_active_transaction_title"
|
||||
android:id="@+id/text_transaction_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:text="Preparing 1.01 ZEC"
|
||||
android:textSize="@dimen/text_size_body_1"
|
||||
android:layout_marginTop="16dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/home_past_transaction_label"
|
||||
android:textColor="@color/text_dark"
|
||||
android:textSize="@dimen/text_size_body_2"
|
||||
android:textStyle="bold"
|
||||
android:transitionName="@string/transition_active_transaction_title"
|
||||
app:layout_constraintBottom_toTopOf="@id/text_active_transaction_subtitle"
|
||||
app:layout_constraintStart_toEndOf="@id/lottie_active_transaction"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header_active_transaction"
|
||||
app:layout_goneMarginTop="0dp" />
|
||||
|
||||
<!-- Transactions -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_transactions"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:clipToPadding="false"
|
||||
|
||||
android:paddingBottom="72dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_transaction_header"
|
||||
tools:itemCount="15"
|
||||
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_transaction"
|
||||
tools:orientation="vertical" />
|
||||
|
||||
<!-- Empty: image -->
|
||||
<ImageView
|
||||
android:id="@+id/image_empty_wallet"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
app:layout_constraintVertical_bias="0.281966"
|
||||
app:srcCompat="@drawable/ic_emptywallet" />
|
||||
|
||||
<!-- Empty: message -->
|
||||
<TextView
|
||||
android:id="@+id/text_active_transaction_subtitle"
|
||||
android:id="@+id/text_empty_wallet_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="to zsapling...123456789"
|
||||
android:textSize="@dimen/text_size_caption"
|
||||
android:transitionName="@string/transition_active_transaction_address"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/text_active_transaction_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_active_transaction_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_active_transaction_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:textColor="@color/text_dark_dimmed"
|
||||
android:textSize="@dimen/text_size_h5"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:padding="16dp"
|
||||
android:text="@string/home_empty_wallet"
|
||||
android:textColor="#AAAAAA"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/image_empty_wallet" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_active_transaction_cancel"
|
||||
|
||||
<!-- -->
|
||||
<!-- Groups -->
|
||||
<!-- -->
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_active_transaction_items"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:text="cancel"
|
||||
android:textColor="@color/selector_red_button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:constraint_referenced_ids="text_active_transaction_header,header_active_transaction" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_content_view_items"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="text_transaction_header,recycler_transactions" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_empty_view_items"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="image_empty_wallet,text_empty_wallet_message" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- Label: Past Activity -->
|
||||
<TextView
|
||||
android:id="@+id/text_transaction_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:text="Past Activity"
|
||||
android:textColor="@color/text_dark"
|
||||
android:textSize="@dimen/text_size_body_2"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/header_active_transaction" />
|
||||
|
||||
<!-- Transactions -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_transactions"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:clipToPadding="false"
|
||||
|
||||
android:paddingBottom="72dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_transaction_header"
|
||||
tools:itemCount="15"
|
||||
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_transaction"
|
||||
tools:orientation="vertical" />
|
||||
|
||||
<!-- Empty: image -->
|
||||
<ImageView
|
||||
android:id="@+id/image_empty_wallet"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.281966"
|
||||
app:srcCompat="@drawable/ic_emptywallet" />
|
||||
|
||||
<!-- Empty: message -->
|
||||
<TextView
|
||||
android:id="@+id/text_wallet_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:padding="16dp"
|
||||
android:text="@string/home_empty_wallet"
|
||||
android:textColor="#AAAAAA"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/image_empty_wallet" />
|
||||
|
||||
|
||||
<!-- -->
|
||||
<!-- Groups -->
|
||||
<!-- -->
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_full_view_items"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="text_transaction_header,recycler_transactions" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_empty_view_items"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="image_empty_wallet,text_wallet_message" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</layout>
|
|
@ -12,117 +12,119 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<cash.z.android.wallet.ui.view.CollapsingMotionToolbar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container_home_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:layoutDescription="@xml/scene_fragment_home_header"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"
|
||||
tools:showIn="@layout/fragment_home">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<Space
|
||||
android:id="@+id/space_left_icon"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="?attr/actionBarSize"/>
|
||||
|
||||
<!-- Toolbar -->
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/home_toolbar"
|
||||
<cash.z.android.wallet.ui.view.CollapsingMotionToolbar
|
||||
android:id="@+id/container_home_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:popupTheme="@style/ZcashTheme.PopupOverlay" />
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:layoutDescription="@xml/scene_fragment_home_header"
|
||||
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"
|
||||
tools:showIn="@layout/fragment_home">
|
||||
|
||||
<!-- balance -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:shadowColor="@color/text_shadow"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="8"
|
||||
android:shadowRadius="24"
|
||||
tools:text="35.021"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="60dp" />
|
||||
<Space
|
||||
android:id="@+id/space_left_icon"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="?attr/actionBarSize" />
|
||||
|
||||
<!-- balance: empty -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:shadowColor="@color/text_shadow"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="8"
|
||||
android:shadowRadius="24"
|
||||
android:text="0"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="60dp" />
|
||||
<!-- Toolbar -->
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/home_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:popupTheme="@style/ZcashTheme.PopupOverlay" />
|
||||
|
||||
<!-- Zec symbol: shadow -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance_shadow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="#B3000000"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
<!-- balance -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:shadowColor="@color/text_shadow"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="8"
|
||||
android:shadowRadius="24"
|
||||
tools:text="35.021"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="60dp" />
|
||||
|
||||
<!-- Zec symbol -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
<!-- balance: empty -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:shadowColor="@color/text_shadow"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="8"
|
||||
android:shadowRadius="24"
|
||||
android:text="0"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="60dp" />
|
||||
|
||||
<!-- Zec symbol empty: shadow -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance_shadow_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="#B3000000"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
<!-- Zec symbol: shadow -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance_shadow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="#B3000000"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
|
||||
<!-- Zec symbol empty -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
<!-- Zec symbol -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
|
||||
<!-- Balance includes active transactions -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_includes_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textColor="@color/text_light_dimmed"
|
||||
android:textSize="@dimen/text_size_caption" />
|
||||
<!-- Zec symbol empty: shadow -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance_shadow_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="#B3000000"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_balance_usd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="$5,459.32"
|
||||
android:textColor="@color/text_light_dimmed"
|
||||
android:textSize="24dp" />
|
||||
<!-- Zec symbol empty -->
|
||||
<ImageView
|
||||
android:id="@+id/image_zec_symbol_balance_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_zec_symbol" />
|
||||
|
||||
<!-- Balance includes active transactions -->
|
||||
<TextView
|
||||
android:id="@+id/text_balance_includes_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textColor="@color/text_light_dimmed"
|
||||
android:textSize="@dimen/text_size_caption" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_balance_usd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="$5,459.32"
|
||||
android:textColor="@color/text_light_dimmed"
|
||||
android:textSize="24dp" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableStart="@drawable/ic_zec_symbol"
|
||||
android:drawableLeft="@drawable/ic_zec_symbol"
|
||||
android:drawablePadding="6dp"
|
||||
android:text="is a currency symbol for ZEC"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="16dp"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/text_balance_zec_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableStart="@drawable/ic_zec_symbol"
|
||||
android:drawableLeft="@drawable/ic_zec_symbol"
|
||||
android:drawablePadding="6dp"
|
||||
android:text="is a currency symbol for ZEC"
|
||||
android:textColor="@color/zcashWhite"
|
||||
android:textSize="16dp" />
|
||||
|
||||
</cash.z.android.wallet.ui.view.CollapsingMotionToolbar>
|
||||
</cash.z.android.wallet.ui.view.CollapsingMotionToolbar>
|
||||
</layout>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content_home_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</layout>
|
File diff suppressed because one or more lines are too long
|
@ -33,6 +33,7 @@
|
|||
<color name="zcashBlack">#00000000</color>
|
||||
<color name="zcashPrimaryMedium">#136E6E</color>
|
||||
<color name="zcashRed">#B00016</color>
|
||||
<color name="zcashYellow">#f4b728</color>
|
||||
|
||||
<!-- -->
|
||||
<!-- named colors -->
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<!-- General -->
|
||||
<string name="cancel">cancel</string>
|
||||
<string name="cancelled">cancelled</string>
|
||||
<string name="ok_allcaps">OK</string>
|
||||
|
||||
<!-- Destinations -->
|
||||
<string name="destination_title_home" />
|
||||
|
@ -36,10 +37,21 @@
|
|||
<string name="transition_active_transaction_address">transition_active_transaction_address</string>
|
||||
<string name="transition_active_transaction_card">transition_active_transaction_card</string>
|
||||
|
||||
|
||||
<!-- -->
|
||||
<!-- Screen copy -->
|
||||
<string name="receive_address_title">Your Zcash shielded address</string>
|
||||
<!-- -->
|
||||
|
||||
<!-- Home -->
|
||||
<string name="home_empty_wallet">Your wallet is empty.</string>
|
||||
<string name="home_empty_wallet_updating">Updating your wallet...</string>
|
||||
<string name="home_empty_wallet_collapse">Future transactions will show up here.</string>
|
||||
<string name="home_current_transaction_label">Current Activity</string>
|
||||
<string name="home_past_transaction_label">Past Activity</string>
|
||||
|
||||
|
||||
<!-- Receive -->
|
||||
<string name="receive_address_title">Your Zcash shielded address</string>
|
||||
|
||||
<!-- Send -->
|
||||
<string name="send_hint_input_zcash_address">Enter a Zcash address</string>
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:motion="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Transition
|
||||
motion:constraintSetEnd="@+id/end"
|
||||
motion:constraintSetStart="@+id/start">
|
||||
|
||||
|
||||
<ConstraintSet android:id="@id/start">
|
||||
<Constraint
|
||||
android:id="@id/text_balance_zec_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
motion:layout_constraintBottom_toBottomOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toTopOf="parent"
|
||||
motion:layout_constraintVertical_bias="0.36"/>
|
||||
</ConstraintSet>
|
||||
|
||||
<ConstraintSet android:id="@id/end">
|
||||
<Constraint
|
||||
android:id="@id/text_balance_zec_empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha='0.0'
|
||||
motion:layout_constraintBottom_toBottomOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toTopOf="parent"
|
||||
motion:layout_constraintVertical_bias="0.36"/>
|
||||
</ConstraintSet>
|
||||
|
||||
<KeyFrameSet>
|
||||
|
||||
<KeyAttribute
|
||||
android:alpha="0.0"
|
||||
motion:framePosition="10"
|
||||
motion:target="@id/text_balance_zec_empty" />
|
||||
|
||||
</KeyFrameSet>
|
||||
</Transition>
|
||||
|
||||
</MotionScene>
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:motion="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Transition
|
||||
motion:constraintSetEnd="@+id/end"
|
||||
motion:constraintSetStart="@+id/start">
|
||||
|
||||
|
||||
<ConstraintSet android:id="@id/start">
|
||||
|
||||
<Constraint
|
||||
android:id="@id/text_balance_zec"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
motion:layout_constraintBottom_toBottomOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toTopOf="parent"
|
||||
motion:layout_constraintVertical_bias="0.36">
|
||||
<CustomAttribute
|
||||
motion:attributeName="textSize"
|
||||
motion:customFloatValue="60.0" />
|
||||
</Constraint>
|
||||
|
||||
</ConstraintSet>
|
||||
|
||||
<ConstraintSet android:id="@id/end">
|
||||
|
||||
<Constraint
|
||||
android:id="@id/text_balance_zec"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
motion:layout_constraintBottom_toBottomOf="@id/space_left_icon"
|
||||
motion:layout_constraintStart_toEndOf="@id/space_left_icon"
|
||||
motion:layout_constraintTop_toTopOf="@id/space_left_icon">
|
||||
<CustomAttribute
|
||||
motion:attributeName="textSize"
|
||||
motion:customFloatValue="24.0" />
|
||||
</Constraint>
|
||||
</ConstraintSet>
|
||||
|
||||
<KeyFrameSet>
|
||||
|
||||
<KeyPosition
|
||||
motion:curveFit="spline"
|
||||
motion:framePosition="80"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:pathMotionArc="startVertical"
|
||||
motion:percentX="0.36"
|
||||
motion:target="@id/text_balance_zec" />
|
||||
|
||||
</KeyFrameSet>
|
||||
</Transition>
|
||||
|
||||
</MotionScene>
|
Loading…
Reference in New Issue