Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basket functionality #53

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AndroidTestAutomationStarter/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ dependencies {
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:recyclerview-v7:26.1.0'
kapt 'com.google.dagger:dagger-compiler:2.11'
implementation 'com.google.dagger:dagger:2.11'
kapt 'com.google.dagger:dagger-compiler:2.10'
implementation 'com.google.dagger:dagger:2.10'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<activity android:name=".activities.ProductListActivity" />
<activity android:name=".activities.ProductDetailsActivity" />
<activity android:name=".activities.BasketActivity"></activity>
<activity android:name=".activities.CheckoutActivity"></activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.novoda.androidstoreexample.activities

import android.content.Intent
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.view.View
import com.novoda.androidstoreexample.R
import com.novoda.androidstoreexample.adapters.BasketAdapter
import com.novoda.androidstoreexample.dagger.basket.BasketModule
import com.novoda.androidstoreexample.dagger.component.AppComponent
import com.novoda.androidstoreexample.listener.BasketAdapterListener
import com.novoda.androidstoreexample.models.Order
import com.novoda.androidstoreexample.models.Product
import com.novoda.androidstoreexample.mvp.presenter.BasketPresenter
import com.novoda.androidstoreexample.mvp.view.BasketView
import com.novoda.androidstoreexample.utilities.PRODUCT_ID_EXTRA
import kotlinx.android.synthetic.main.activity_basket.*
import javax.inject.Inject

class BasketActivity : BaseActivity(), BasketView {

@Inject
lateinit var presenter: BasketPresenter

Expand All @@ -30,16 +34,43 @@ class BasketActivity : BaseActivity(), BasketView {
}

override fun showBasketItems(orders: List<Order>) {
val basketAdapter = BasketAdapter(this, orders) {
val listener = object: BasketAdapterListener {
override fun onProductImageClicked(product: Product) {
presenter.onBasketItemClicked(product)
}

override fun onIncreaseAmountClicked(product: Product) {
presenter.onIncreaseItemClicked(product)
}

override fun onDecreaseAmountClicked(product: Product) {
presenter.onDecreaseAmountClicked(product)
}
}
val basketAdapter = BasketAdapter(this, orders, listener)
basketList.layoutManager = LinearLayoutManager(this)
basketList.adapter = basketAdapter
}

override fun showTotalAmountOfBasket(totalPrice: Int) {
basket_total_text_field.text = applicationContext.getString(R.string.price_template, totalPrice)
}

override fun onProductClicked(product: Product) {
val intent = Intent(this, ProductDetailsActivity::class.java)
intent.putExtra(PRODUCT_ID_EXTRA, product.id)
startActivity(intent)
}

override fun getActivityLayout(): Int {
return R.layout.activity_basket
}

override fun onCheckoutClicked(view: View) {
val intent = Intent(this, CheckoutActivity::class.java)
startActivity(intent)
}

override fun injectDependencies(appComponent: AppComponent) {
appComponent.injectBasket(BasketModule(this)).inject(this)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.novoda.androidstoreexample.activities

import android.os.Bundle
import com.novoda.androidstoreexample.R
import com.novoda.androidstoreexample.dagger.checkout.CheckoutModule
import com.novoda.androidstoreexample.dagger.component.AppComponent
import com.novoda.androidstoreexample.mvp.presenter.CheckoutPresenter
import kotlinx.android.synthetic.main.activity_checkout.*
import javax.inject.Inject

class CheckoutActivity : BaseActivity() {
@Inject
lateinit var presenter: CheckoutPresenter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_checkout)
buy_button.setOnClickListener {
presenter.onBuyClick()
}
}

override fun getActivityLayout(): Int {
return R.layout.activity_checkout
}

override fun injectDependencies(appComponent: AppComponent) {
appComponent.injectCheckout(CheckoutModule(this)).inject(this)
}

override fun showProgress() {
}

override fun hideProgress() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.novoda.androidstoreexample.activities

import android.content.Intent
import android.os.Bundle
import android.view.View
import com.novoda.androidstoreexample.R
import com.novoda.androidstoreexample.dagger.component.AppComponent
import com.novoda.androidstoreexample.dagger.confirmation.ConfirmationModule
import com.novoda.androidstoreexample.mvp.presenter.ConfirmationPresenter
import com.novoda.androidstoreexample.mvp.view.ConfirmationView
import kotlinx.android.synthetic.main.activity_purchase_confirmation.*
import javax.inject.Inject

class ConfirmationActivity : BaseActivity(), ConfirmationView {
override fun getActivityLayout(): Int {
return R.layout.activity_purchase_confirmation
}

@Inject
lateinit var presenter: ConfirmationPresenter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_purchase_confirmation)
home_button.setOnClickListener {
presenter.onHomeClicked()
}
}

override fun injectDependencies(appComponent: AppComponent) {
appComponent.injectConfirmation(ConfirmationModule(this)).inject(this)
}


override fun onHomeClicked(view: View) {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}

override fun showProgress() {
}

override fun hideProgress() {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ProductDetailsActivity : BaseActivity(), ProductDetailView {
productDetailImage.setImageResource(resourceId)
productDetailTitle.text = product.title
productDetailDescription.text = product.productDescription
productDetailPrice.text = product.price
productDetailPrice.text = applicationContext.getString(R.string.price_template, product.price)
}

override fun getActivityLayout(): Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@ import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import com.novoda.androidstoreexample.R
import com.novoda.androidstoreexample.listener.BasketAdapterListener
import com.novoda.androidstoreexample.models.Order
import com.novoda.androidstoreexample.utilities.ImageHelper

class BasketAdapter(
private val context: Context,
private val orders: List<Order>,
private val itemClicked: (Int) -> Unit
private val listener: BasketAdapterListener
) : RecyclerView.Adapter<BasketAdapter.Holder>() {

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): Holder {
val view = LayoutInflater.from(context).inflate(R.layout.basket_item, parent, false)
return Holder(view, itemClicked)
return Holder(view, listener)
}

override fun getItemCount(): Int {
Expand All @@ -30,16 +32,33 @@ class BasketAdapter(
holder?.bindProducts(orders[position], context)
}

inner class Holder(itemView: View, private val itemClicked: (Int) -> Unit) : RecyclerView.ViewHolder(itemView) {
inner class Holder(itemView: View, private val productListener: BasketAdapterListener) : RecyclerView.ViewHolder(itemView) {
private val productImage = itemView.findViewById<ImageView>(R.id.basketProductImage)
private val productTitle = itemView.findViewById<TextView>(R.id.basketProductTitle)
private val numberOfProducts = itemView.findViewById<TextView>(R.id.NumberOfItemsTextField)
private val plusButton = itemView.findViewById<Button>(R.id.basket_view_increase_button)
private val minusButton = itemView.findViewById<Button>(R.id.basket_view_decrease_button)
private val numberOfProducts = itemView.findViewById<TextView>(R.id.number_of_items_text_field)
private val priceField = itemView.findViewById<TextView>(R.id.price_per_item_textview)
private val totalField = itemView.findViewById<TextView>(R.id.total_text_view)

fun bindProducts(order: Order, context: Context) {
val resourceId: Int = ImageHelper().getResourceIdForImage(context, order.product.image)
productImage?.setImageResource(resourceId)
productTitle?.text = order.product.title
numberOfProducts?.text = order.numberOfItems.toString()
with(order) {
val resourceId: Int = ImageHelper().getResourceIdForImage(context, product.image)
productImage?.setImageResource(resourceId)
productImage?.setOnClickListener{
productListener.onProductImageClicked(product)
}
plusButton?.setOnClickListener{
productListener.onIncreaseAmountClicked(product)
}
minusButton?.setOnClickListener{
productListener.onDecreaseAmountClicked(product)
}
priceField?.text = context.getString(R.string.price_template, product.price)
totalField?.text = context.getString(R.string.price_template, amount)
productTitle?.text = order.product.title
numberOfProducts?.text = order.numberOfItems.toString()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.novoda.androidstoreexample.adapters

import android.content.Context
import android.content.res.Resources
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
Expand Down Expand Up @@ -40,7 +41,7 @@ class ProductListAdapter(
val resourceId: Int = ImageHelper().getResourceIdForImage(context, product.image)
productImage?.setImageResource(resourceId)
productName?.text = product.title
productPrice?.text = product.price
productPrice?.text = context.getString(R.string.price_template, product.price)
itemView.setOnClickListener { itemClick(product.id) }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ class App : Application() {
super.onCreate()
component = DaggerAppComponent.create()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.novoda.androidstoreexample.dagger.checkout

import com.novoda.androidstoreexample.activities.CheckoutActivity
import dagger.Subcomponent

@Subcomponent(modules = arrayOf(CheckoutModule::class))
interface CheckoutComponent {
fun inject(checkoutActivity: CheckoutActivity)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.novoda.androidstoreexample.dagger.checkout

import com.novoda.androidstoreexample.mvp.presenter.CheckoutPresenter
import com.novoda.androidstoreexample.mvp.presenter.impl.CheckoutPresenterImpl
import dagger.Module
import dagger.Provides

@Module
class CheckoutModule(private val checkoutView: CheckoutView) {

@Provides
fun providesView(): CheckoutView = checkoutView

@Provides
fun providePresenter(checkoutPresenter: CheckoutPresenterImpl): CheckoutPresenter {
return checkoutPresenter
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import com.novoda.androidstoreexample.dagger.categoryList.CategoryListComponent
import com.novoda.androidstoreexample.dagger.categoryList.CategoryListModule
import com.novoda.androidstoreexample.dagger.categoryList.ProductListComponent
import com.novoda.androidstoreexample.dagger.categoryList.ProductListModule
import com.novoda.androidstoreexample.dagger.checkout.CheckoutComponent
import com.novoda.androidstoreexample.dagger.checkout.CheckoutModule
import com.novoda.androidstoreexample.dagger.confirmation.ConfirmationComponent
import com.novoda.androidstoreexample.dagger.confirmation.ConfirmationModule
import com.novoda.androidstoreexample.dagger.module.BasketServiceModule
import com.novoda.androidstoreexample.dagger.module.ClientModule
import com.novoda.androidstoreexample.dagger.module.HostModule
Expand All @@ -22,4 +26,6 @@ interface AppComponent {
fun injectProducts(productListModule: ProductListModule): ProductListComponent
fun injectProductDetails(productDetailsModule: ProductDetailsModule): ProductDetailsComponent
fun injectBasket(basketModule: BasketModule): BasketComponent
}
fun injectCheckout(checkoutModule: CheckoutModule): CheckoutComponent
fun injectConfirmation(confirmationModule: ConfirmationModule): ConfirmationComponent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.novoda.androidstoreexample.dagger.confirmation

import com.novoda.androidstoreexample.activities.ConfirmationActivity
import dagger.Subcomponent

@Subcomponent(modules = [ConfirmationModule::class])
interface ConfirmationComponent {
fun inject(confirmationActivity: ConfirmationActivity)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.novoda.androidstoreexample.dagger.confirmation

import com.novoda.androidstoreexample.mvp.presenter.ConfirmationPresenter
import com.novoda.androidstoreexample.mvp.presenter.impl.ConfirmationPresenterImpl
import com.novoda.androidstoreexample.mvp.view.ConfirmationView
import dagger.Module
import dagger.Provides

@Module
class ConfirmationModule(private val confirmationView: ConfirmationView) {

@Provides
fun providesView(): ConfirmationView = confirmationView

@Provides
fun providePresenter(confirmationPresenter: ConfirmationPresenterImpl): ConfirmationPresenter {
return confirmationPresenter
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.novoda.androidstoreexample.listener

import com.novoda.androidstoreexample.models.Product

interface BasketAdapterListener {
fun onProductImageClicked(product: Product)

fun onIncreaseAmountClicked(product: Product)

fun onDecreaseAmountClicked(product: Product)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package com.novoda.androidstoreexample.models

data class Order(val product: Product, val numberOfItems: Int)
data class Order(val product: Product, val numberOfItems: Int) {
val amount: Int = product.price * numberOfItems
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.squareup.moshi.Json
data class Product(
val id: Int,
val title: String,
val price: String,
val price: Int,
val image: String,
@Json(name = "product_description") val productDescription: String
)
Loading