Skip to content

Commit

Permalink
Create GooglePayViewHolder for PaymentMethodsAdapter (#1944)
Browse files Browse the repository at this point in the history
- Create `google_pay_row` layout with `stripe_google_pay_mark` mark [0].
- Convert PaymentMethodsAdapter's ViewHolders into a sealed class.

[0] https://developers.google.com/pay/api/android/guides/brand-guidelines#google-pay-logo-mark
  • Loading branch information
mshafrir-stripe authored Dec 11, 2019
1 parent 030073a commit 75eda3a
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 58 deletions.
60 changes: 60 additions & 0 deletions stripe/res/drawable/stripe_google_pay_mark.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="425dp"
android:height="272dp"
android:viewportWidth="425"
android:viewportHeight="272">
<path
android:pathData="M386.731,0.09L38.04,0.09C36.587,0.09 35.132,0.09 33.682,0.097C32.458,0.108 31.237,0.121 30.012,0.154C27.346,0.226 24.657,0.382 22.024,0.857C19.35,1.336 16.86,2.121 14.433,3.357C12.043,4.57 9.86,6.158 7.963,8.051C6.069,9.946 4.481,12.126 3.267,14.516C2.03,16.942 1.245,19.43 0.767,22.105C0.29,24.739 0.133,27.424 0.062,30.086C0.028,31.31 0.013,32.531 0.005,33.751C-0.003,35.203 0,36.655 0,38.109L0,233.841C0,235.295 -0.003,236.744 0.005,238.198C0.013,239.419 0.028,240.643 0.062,241.863C0.133,244.523 0.29,247.211 0.767,249.842C1.245,252.517 2.03,255.005 3.267,257.434C4.481,259.821 6.069,262.004 7.963,263.897C9.86,265.792 12.043,267.38 14.433,268.59C16.86,269.829 19.35,270.614 22.024,271.096C24.657,271.565 27.346,271.724 30.012,271.796C31.237,271.824 32.458,271.842 33.682,271.847C35.132,271.858 36.587,271.858 38.04,271.858L386.731,271.858C388.181,271.858 389.636,271.858 391.086,271.847C392.307,271.842 393.529,271.824 394.758,271.796C397.419,271.724 400.109,271.565 402.747,271.096C405.419,270.614 407.908,269.829 410.338,268.59C412.727,267.38 414.906,265.792 416.805,263.897C418.696,262.004 420.285,259.821 421.501,257.434C422.741,255.005 423.526,252.517 424.001,249.842C424.478,247.211 424.632,244.523 424.704,241.863C424.737,240.643 424.753,239.419 424.76,238.198C424.771,236.744 424.771,235.295 424.771,233.841L424.771,38.109C424.771,36.655 424.771,35.203 424.76,33.751C424.753,32.531 424.737,31.31 424.704,30.086C424.632,27.424 424.478,24.739 424.001,22.105C423.526,19.43 422.741,16.942 421.501,14.516C420.285,12.126 418.696,9.946 416.805,8.051C414.906,6.158 412.727,4.57 410.338,3.357C407.908,2.121 405.419,1.336 402.747,0.857C400.109,0.382 397.419,0.226 394.758,0.154C393.529,0.121 392.307,0.108 391.086,0.097C389.636,0.09 388.181,0.09 386.731,0.09"
android:strokeWidth="1"
android:fillColor="#3C4043"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M386.731,9.148L391.022,9.156C392.182,9.164 393.344,9.176 394.512,9.21C396.544,9.264 398.923,9.374 401.141,9.771C403.065,10.118 404.682,10.646 406.232,11.433C407.764,12.211 409.165,13.231 410.389,14.452C411.619,15.683 412.64,17.086 413.428,18.632C414.213,20.171 414.737,21.777 415.083,23.716C415.478,25.909 415.589,28.291 415.643,30.335C415.676,31.487 415.691,32.641 415.696,33.823C415.707,35.252 415.707,36.678 415.707,38.109L415.707,233.841C415.707,235.272 415.707,236.698 415.696,238.155C415.691,239.309 415.676,240.463 415.643,241.62C415.589,243.659 415.478,246.041 415.078,248.257C414.737,250.17 414.213,251.776 413.423,253.322C412.637,254.866 411.619,256.267 410.395,257.49C409.163,258.721 407.767,259.737 406.217,260.522C404.677,261.306 403.065,261.835 401.159,262.176C398.895,262.578 396.419,262.691 394.553,262.74C393.38,262.768 392.213,262.784 391.014,262.789C389.59,262.799 388.158,262.799 386.731,262.799L38.04,262.799C38.022,262.799 38.004,262.799 37.983,262.799C36.574,262.799 35.16,262.799 33.726,262.789C32.556,262.784 31.388,262.768 30.259,262.743C28.35,262.691 25.871,262.578 23.628,262.178C21.703,261.835 20.091,261.306 18.531,260.511C16.996,259.734 15.6,258.719 14.369,257.485C13.147,256.267 12.131,254.869 11.345,253.322C10.558,251.779 10.032,250.168 9.685,248.232C9.287,246.018 9.177,243.648 9.121,241.62C9.09,240.461 9.077,239.299 9.069,238.147L9.064,234.741L9.064,37.211L9.069,33.813C9.077,32.651 9.09,31.492 9.121,30.333C9.177,28.301 9.287,25.929 9.69,23.698C10.032,21.782 10.558,20.169 11.348,18.617C12.128,17.083 13.147,15.683 14.374,14.457C15.598,13.231 17.002,12.216 18.544,11.431C20.086,10.643 21.703,10.118 23.628,9.771C25.845,9.374 28.224,9.264 30.261,9.21C31.421,9.176 32.584,9.164 33.736,9.156L38.04,9.148L386.731,9.148"
android:strokeWidth="1"
android:fillColor="#FFFFFE"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M204.506,142.249L204.506,180.983L192.404,180.983L192.404,85.368L224.501,85.368C232.243,85.216 239.76,88.19 245.247,93.679C256.221,104.049 256.898,121.51 246.6,132.718C246.149,133.176 245.698,133.633 245.247,134.091C239.609,139.504 232.694,142.249 224.501,142.249L204.506,142.249ZM204.506,97.111L204.506,130.507L224.801,130.507C229.311,130.66 233.671,128.83 236.753,125.551C243.067,118.918 242.917,108.243 236.377,101.838C233.295,98.788 229.161,97.111 224.801,97.111L204.506,97.111Z"
android:strokeWidth="1"
android:fillColor="#3C4043"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M281.853,113.428C290.798,113.428 297.864,115.868 303.051,120.671C308.237,125.475 310.793,132.185 310.793,140.648L310.793,180.983L299.217,180.983L299.217,171.91L298.691,171.91C293.655,179.382 287.04,183.118 278.696,183.118C271.631,183.118 265.617,180.983 260.882,176.713C256.221,172.749 253.59,166.878 253.741,160.701C253.741,153.915 256.296,148.578 261.333,144.537C266.369,140.496 273.134,138.513 281.553,138.513C288.769,138.513 294.632,139.886 299.292,142.478L299.292,139.657C299.292,135.463 297.488,131.498 294.331,128.754C291.099,125.856 286.965,124.255 282.68,124.255C275.915,124.255 270.578,127.152 266.67,132.947L255.996,126.161C261.709,117.698 270.353,113.428 281.853,113.428ZM266.219,160.93C266.219,164.133 267.722,167.106 270.202,168.936C272.908,171.071 276.216,172.215 279.598,172.139C284.71,172.139 289.596,170.08 293.204,166.42C297.188,162.608 299.217,158.109 299.217,152.924C295.459,149.874 290.197,148.349 283.432,148.425C278.546,148.425 274.412,149.645 271.104,152.009C267.872,154.373 266.219,157.346 266.219,160.93Z"
android:strokeWidth="1"
android:fillColor="#3C4043"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M377.241,115.563l-40.44,94.166l-12.478,0l15.033,-32.939l-26.534,-61.227l13.154,0l19.168,46.969l0.226,0l18.717,-46.969z"
android:strokeWidth="1"
android:fillColor="#3C4043"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M155.572,133.862C155.572,130.126 155.271,126.39 154.67,122.73L103.631,122.73L103.631,143.851L132.871,143.851C131.669,150.637 127.76,156.737 122.047,160.549L122.047,174.274L139.486,174.274C149.709,164.743 155.572,150.637 155.572,133.862Z"
android:strokeWidth="1"
android:fillColor="#4285F4"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M103.631,187.541C118.214,187.541 130.541,182.661 139.486,174.274L122.047,160.549C117.161,163.904 110.923,165.81 103.631,165.81C89.5,165.81 77.548,156.127 73.264,143.164L55.299,143.164L55.299,157.346C64.469,175.875 83.186,187.541 103.631,187.541Z"
android:strokeWidth="1"
android:fillColor="#34A853"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M73.264,143.164C71.009,136.378 71.009,128.982 73.264,122.12L73.264,108.014L55.299,108.014C47.556,123.492 47.556,141.792 55.299,157.27L73.264,143.164Z"
android:strokeWidth="1"
android:fillColor="#FBBC04"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M103.631,99.474C111.374,99.322 118.815,102.295 124.378,107.709L139.862,92.002C130.015,82.7 117.086,77.591 103.631,77.744C83.186,77.744 64.469,89.486 55.299,108.014L73.264,122.196C77.548,109.158 89.5,99.474 103.631,99.474Z"
android:strokeWidth="1"
android:fillColor="#EA4335"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>
16 changes: 16 additions & 0 deletions stripe/res/layout/google_pay_row.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/stripe_list_row_end_padding"
android:paddingStart="@dimen/stripe_list_row_start_padding"
>

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stripe_google_pay_mark"
android:contentDescription="@null"/>

</FrameLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal class PaymentMethodSwipeCallback(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
return if (viewHolder is PaymentMethodsAdapter.PaymentMethodViewHolder) {
return if (viewHolder is PaymentMethodsAdapter.ViewHolder.PaymentMethodViewHolder) {
// only allow swiping on Payment Method items
super.getSwipeDirs(recyclerView, viewHolder)
} else {
Expand All @@ -68,7 +68,7 @@ internal class PaymentMethodSwipeCallback(
isCurrentlyActive: Boolean
) {
super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
if (viewHolder is PaymentMethodsAdapter.PaymentMethodViewHolder) {
if (viewHolder is PaymentMethodsAdapter.ViewHolder.PaymentMethodViewHolder) {
val itemView = viewHolder.itemView

val startTransition = itemView.width * START_TRANSITION_THRESHOLD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ class PaymentMethodsActivity : AppCompatActivity() {
args: PaymentMethodsActivityStarter.Args
) {
adapter = PaymentMethodsAdapter(
viewModel.selectedPaymentMethodId,
args,
args.paymentMethodTypes
args.paymentMethodTypes,
viewModel.selectedPaymentMethodId
)

adapter.listener = object : PaymentMethodsAdapter.Listener {
Expand Down
109 changes: 69 additions & 40 deletions stripe/src/main/java/com/stripe/android/view/PaymentMethodsAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import java.util.ArrayList
* A [RecyclerView.Adapter] that holds a set of [MaskedCardView] items for a given set
* of [PaymentMethod] objects.
*/
internal class PaymentMethodsAdapter @JvmOverloads internal constructor(
initiallySelectedPaymentMethodId: String?,
internal class PaymentMethodsAdapter constructor(
private val intentArgs: PaymentMethodsActivityStarter.Args,
private val addableTypes: List<PaymentMethod.Type> = listOf(PaymentMethod.Type.Card)
private val addableTypes: List<PaymentMethod.Type> = listOf(PaymentMethod.Type.Card),
initiallySelectedPaymentMethodId: String? = null
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

internal val paymentMethods = ArrayList<PaymentMethod>()
Expand Down Expand Up @@ -52,15 +52,16 @@ internal class PaymentMethodsAdapter @JvmOverloads internal constructor(
return if (position < paymentMethods.size) {
val type = paymentMethods[position].type
if (PaymentMethod.Type.Card.code == type) {
TYPE_CARD
ViewType.Card.ordinal
} else {
super.getItemViewType(position)
}
} else {
val paymentMethodType = addableTypes[getAddableTypesPosition(position)]
val paymentMethodType =
addableTypes[getAddableTypesPosition(position)]
return when (paymentMethodType) {
PaymentMethod.Type.Card -> TYPE_ADD_CARD
PaymentMethod.Type.Fpx -> TYPE_ADD_FPX
PaymentMethod.Type.Card -> ViewType.AddCard.ordinal
PaymentMethod.Type.Fpx -> ViewType.AddFpx.ordinal
else ->
throw IllegalArgumentException(
"Unsupported PaymentMethod type: ${paymentMethodType.code}")
Expand All @@ -77,7 +78,7 @@ internal class PaymentMethodsAdapter @JvmOverloads internal constructor(
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is PaymentMethodViewHolder) {
if (holder is ViewHolder.PaymentMethodViewHolder) {
val paymentMethod = paymentMethods[position]
holder.setPaymentMethod(paymentMethod)
holder.setSelected(paymentMethod.id == selectedPaymentMethodId)
Expand Down Expand Up @@ -109,31 +110,48 @@ internal class PaymentMethodsAdapter @JvmOverloads internal constructor(
notifyItemChanged(position)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
TYPE_CARD -> createPaymentMethodViewHolder(parent)
TYPE_ADD_CARD -> createAddCardPaymentMethodViewHolder(parent)
TYPE_ADD_FPX -> createAddFpxPaymentMethodViewHolder(parent)
else -> throw IllegalArgumentException("Unsupported viewType: $viewType")
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
return when (ViewType.values()[viewType]) {
ViewType.Card -> createPaymentMethodViewHolder(parent)
ViewType.AddCard -> createAddCardPaymentMethodViewHolder(parent)
ViewType.AddFpx -> createAddFpxPaymentMethodViewHolder(parent)
ViewType.GooglePay -> createGooglePayViewHolder(parent)
}
}

private fun createAddCardPaymentMethodViewHolder(parent: ViewGroup): AddCardPaymentMethodViewHolder {
return AddCardPaymentMethodViewHolder(
private fun createAddCardPaymentMethodViewHolder(
parent: ViewGroup
): ViewHolder.AddCardPaymentMethodViewHolder {
return ViewHolder.AddCardPaymentMethodViewHolder(
AddPaymentMethodCardRowView(parent.context as Activity, intentArgs)
)
}

private fun createAddFpxPaymentMethodViewHolder(parent: ViewGroup): AddFpxPaymentMethodViewHolder {
return AddFpxPaymentMethodViewHolder(
private fun createAddFpxPaymentMethodViewHolder(
parent: ViewGroup
): ViewHolder.AddFpxPaymentMethodViewHolder {
return ViewHolder.AddFpxPaymentMethodViewHolder(
AddPaymentMethodFpxRowView(parent.context as Activity, intentArgs)
)
}

private fun createPaymentMethodViewHolder(parent: ViewGroup): PaymentMethodViewHolder {
private fun createPaymentMethodViewHolder(
parent: ViewGroup
): ViewHolder.PaymentMethodViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.masked_card_row, parent, false)
return PaymentMethodViewHolder(itemView)
return ViewHolder.PaymentMethodViewHolder(itemView)
}

private fun createGooglePayViewHolder(
parent: ViewGroup
): ViewHolder.GooglePayViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.google_pay_row, parent, false)
return ViewHolder.GooglePayViewHolder(itemView)
}

internal fun deletePaymentMethod(paymentMethod: PaymentMethod) {
Expand All @@ -151,35 +169,46 @@ internal class PaymentMethodsAdapter @JvmOverloads internal constructor(
}
}

private fun getAddableTypesPosition(position: Int) = position - paymentMethods.size
private fun getAddableTypesPosition(position: Int): Int {
return position - paymentMethods.size
}

internal class PaymentMethodViewHolder constructor(
itemView: View
) : RecyclerView.ViewHolder(itemView) {
private val cardView: MaskedCardView = itemView.findViewById(R.id.masked_card_item)
internal sealed class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
internal class AddCardPaymentMethodViewHolder(
itemView: View
) : RecyclerView.ViewHolder(itemView)

fun setPaymentMethod(paymentMethod: PaymentMethod) {
cardView.setPaymentMethod(paymentMethod)
}
internal class AddFpxPaymentMethodViewHolder(
itemView: View
) : RecyclerView.ViewHolder(itemView)

fun setSelected(selected: Boolean) {
cardView.isSelected = selected
}
}
internal class GooglePayViewHolder(
itemView: View
) : RecyclerView.ViewHolder(itemView)

internal class PaymentMethodViewHolder constructor(
itemView: View
) : ViewHolder(itemView) {
private val cardView: MaskedCardView = itemView.findViewById(R.id.masked_card_item)

internal class AddCardPaymentMethodViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView)
fun setPaymentMethod(paymentMethod: PaymentMethod) {
cardView.setPaymentMethod(paymentMethod)
}

internal class AddFpxPaymentMethodViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView)
fun setSelected(selected: Boolean) {
cardView.isSelected = selected
}
}
}

internal interface Listener {
fun onClick(paymentMethod: PaymentMethod)
}

private companion object {
private const val TYPE_CARD = 1
private const val TYPE_ADD_CARD = 2
private const val TYPE_ADD_FPX = 3
private enum class ViewType {
Card,
AddCard,
AddFpx,
GooglePay
}
}
Loading

0 comments on commit 75eda3a

Please sign in to comment.