RnD for caching cart and also adding items to cart locally.

Integrated product view api for viewing product.

Added removing cart item functionality from product view fragment.

Added callback to listen removal changes when gone to cart from product view fragment.

Debugged crash with configuration changes with multiple fragments in an activity with no public constructor.
And issue with no saved state when configuration is changed.

Understood and integrated navigation-safe-args in ShopActivity.
This commit is contained in:
2024-07-31 20:52:15 +05:30
parent 4d393b0fcf
commit 73e6a9f3fc
27 changed files with 489 additions and 203 deletions

View File

@@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.androidApplication) alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid) alias(libs.plugins.jetbrainsKotlinAndroid)
id("kotlin-parcelize") id("kotlin-parcelize")
alias(libs.plugins.navigationSafeArgs)
} }
android { android {

View File

@@ -180,7 +180,7 @@ class MyListFragment : Fragment() {
karaokeTxt.text = getString(R.string.karaoke) karaokeTxt.text = getString(R.string.karaoke)
gamesTxt.text = getString(R.string.games) gamesTxt.text = getString(R.string.games)
noData.text = getString(R.string.no_favorites_added) noDataTxt.text = getString(R.string.no_favorites_added)
if (webSeriesEAdapter.currentList.isNotEmpty()){ if (webSeriesEAdapter.currentList.isNotEmpty()){
webSeriesEAdapter.notifyItemRangeChanged(0, webSeriesEAdapter.currentList.size) webSeriesEAdapter.notifyItemRangeChanged(0, webSeriesEAdapter.currentList.size)

View File

@@ -12,6 +12,7 @@ import com.woka.shop.models.createorder.CreateOrderRequestData
import com.woka.shop.models.createorder.CreateOrderResponse import com.woka.shop.models.createorder.CreateOrderResponse
import com.woka.shop.models.edd.EDDResponse import com.woka.shop.models.edd.EDDResponse
import com.woka.shop.models.productlisting.ProductListingResponse import com.woka.shop.models.productlisting.ProductListingResponse
import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.models.subcategorylisting.SubCategoryResponse import com.woka.shop.models.subcategorylisting.SubCategoryResponse
import com.woka.shop.models.superlisting.SuperCategoryResponse import com.woka.shop.models.superlisting.SuperCategoryResponse
import okhttp3.FormBody import okhttp3.FormBody
@@ -35,6 +36,9 @@ interface ShopApiService {
@POST("v2/shop_product_listing") @POST("v2/shop_product_listing")
suspend fun productListing(@Body formBody: FormBody): Response<ApiResponse<ProductListingResponse>> suspend fun productListing(@Body formBody: FormBody): Response<ApiResponse<ProductListingResponse>>
@POST("shop_product_view")
suspend fun productView(@Body formBody: FormBody): Response<ApiResponse<ArrayList<ShopProduct>>>
// cart // cart
@GET("cart_listing") @GET("cart_listing")
suspend fun cartListing(): Response<ApiResponse<CartResponse>> suspend fun cartListing(): Response<ApiResponse<CartResponse>>

View File

@@ -75,6 +75,16 @@ object ShopRepository {
} }
} }
suspend fun getProductData(id: Int): ApiResult<ArrayList<ShopProduct>> {
return handleApiCall {
apiService.productView(
FormBody.Builder()
.add("product_id", "$id")
.build()
)
}
}
// cart listing with loose caching // cart listing with loose caching
private var cartResponse: CartResponse? = null private var cartResponse: CartResponse? = null

View File

@@ -32,7 +32,7 @@ class CategoryAdapter:
inner class CategoryViewHolder(val binding: CategoryViweHolderBinding) : inner class CategoryViewHolder(val binding: CategoryViweHolderBinding) :
ViewHolder(binding.root) ViewHolder(binding.root)
var onCategoryClickListener: ((BaseCategory) -> Unit)? = null var onCategoryClickListener: ((Int) -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryViewHolder {
return CategoryViewHolder( return CategoryViewHolder(
@@ -52,7 +52,9 @@ class CategoryAdapter:
title.text = category.title title.text = category.title
holder.binding.root.setOnClickListener { holder.binding.root.setOnClickListener {
onCategoryClickListener?.invoke(category) category.id?.let {
onCategoryClickListener?.invoke(it)
}
} }
} }
} }

View File

@@ -7,12 +7,18 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.woka.databinding.ProductImageViewHolderBinding import com.woka.databinding.ProductImageViewHolderBinding
class ProductImagesAdapter( class ProductImagesAdapter: RecyclerView.Adapter<ProductImagesAdapter.ImageViewHolder>(){
private val imageList: ArrayList<String>
) : RecyclerView.Adapter<ProductImagesAdapter.ImageViewHolder>(){
inner class ImageViewHolder(val binding: ProductImageViewHolderBinding): ViewHolder(binding.root) inner class ImageViewHolder(val binding: ProductImageViewHolderBinding): ViewHolder(binding.root)
private val imageList: ArrayList<String> = ArrayList()
fun submitList(imageList: ArrayList<String>){
this.imageList.clear()
this.imageList.addAll(imageList)
notifyItemRangeChanged(0, imageList.size)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
return ImageViewHolder( return ImageViewHolder(
ProductImageViewHolderBinding.inflate( ProductImageViewHolderBinding.inflate(

View File

@@ -24,7 +24,7 @@ class ShopProductAdapter: ListAdapter<ShopProduct, ShopProductAdapter.ProductVie
inner class ProductViewHolder(val binding: ProductViewHolderBinding): ViewHolder(binding.root) inner class ProductViewHolder(val binding: ProductViewHolderBinding): ViewHolder(binding.root)
var onProductClicked: ((ShopProduct) -> Unit)? = null var onProductClicked: ((Int) -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
return ProductViewHolder( return ProductViewHolder(
@@ -52,7 +52,9 @@ class ShopProductAdapter: ListAdapter<ShopProduct, ShopProductAdapter.ProductVie
price.text = "${product.product_price}" price.text = "${product.product_price}"
root.setOnClickListener { root.setOnClickListener {
onProductClicked?.invoke(product) product.id?.let {
onProductClicked?.invoke(it)
}
} }
} }
} }

View File

@@ -0,0 +1,10 @@
package com.woka.shop.models.productlisting
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class ProductCategory(
val category_name: String?,
val id: Int?
):Parcelable

View File

@@ -19,7 +19,8 @@ data class ShopProduct(
val sku_id: String?, val sku_id: String?,
val stock_status: String?, val stock_status: String?,
val sub_category_master_id: Int?, val sub_category_master_id: Int?,
val tax_value: String? val tax_value: String?,
val category: ProductCategory?
): Parcelable{ ): Parcelable{
constructor(cartItem: CartItem, added_to_cart: Boolean?): this( constructor(cartItem: CartItem, added_to_cart: Boolean?): this(
@@ -36,7 +37,8 @@ data class ShopProduct(
cartItem.sku_id, cartItem.sku_id,
cartItem.stock_status, cartItem.stock_status,
cartItem.sub_category_master_id, cartItem.sub_category_master_id,
cartItem.tax_value cartItem.tax_value,
null
) )
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {

View File

@@ -31,9 +31,6 @@ class CartViewModel: ViewModel() {
var selectedAddressId: Int? = null var selectedAddressId: Int? = null
val eddMap = HashMap<Int, String>() val eddMap = HashMap<Int, String>()
// cart
val removedProducts = ArrayList<ShopProduct>()
// data callbacks // data callbacks
private val repository = ShopRepository private val repository = ShopRepository

View File

@@ -1,6 +1,5 @@
package com.woka.shop.viewmodels package com.woka.shop.viewmodels
import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
@@ -12,9 +11,7 @@ import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.models.subcategorylisting.SubCategoryData import com.woka.shop.models.subcategorylisting.SubCategoryData
import com.woka.shop.models.superlisting.SuperCategory import com.woka.shop.models.superlisting.SuperCategory
import com.woka.utils.PagingData import com.woka.utils.PagingData
import com.woka.utils.TAG
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.collections.HashSet
class ShopViewModel: ViewModel() { class ShopViewModel: ViewModel() {
@@ -122,11 +119,11 @@ class ShopViewModel: ViewModel() {
if (productDataMap.containsKey(key) && productDataMap[key]?.isNotEmpty() == true) { if (productDataMap.containsKey(key) && productDataMap[key]?.isNotEmpty() == true) {
_productListingLiveData.postValue(ApiResult.Success(productDataMap[key])) _productListingLiveData.postValue(ApiResult.Success(productDataMap[key]))
} else { } else {
loadMoreEpisodes(superCategoryId, categoryId, subCategoryId) loadMoreProducts(superCategoryId, categoryId, subCategoryId)
} }
} }
fun loadMoreEpisodes(superCategoryId: String, categoryId: String, subCategoryId: String?) { fun loadMoreProducts(superCategoryId: String, categoryId: String, subCategoryId: String?) {
viewModelScope.launch { viewModelScope.launch {
_productListingLiveData.postValue(ApiResult.Loading()) _productListingLiveData.postValue(ApiResult.Loading())
@@ -176,30 +173,23 @@ class ShopViewModel: ViewModel() {
} }
} }
fun removeProductsFromCart(products: List<ShopProduct>){ suspend fun loadProductData(id: Int): ApiResult<ArrayList<ShopProduct>> {
val toBeReplaced = mutableSetOf<ShopProduct>() return repository.getProductData(id)
for (productSet in productDataMap.values){
toBeReplaced.clear()
for (product in products){
if (productSet.contains(product)){
toBeReplaced.add(product)
}
}
productSet.removeAll(toBeReplaced)
productSet.addAll(toBeReplaced)
}
_productListingLiveData.postValue(ApiResult.Success(productDataMap[""]))
} }
fun clearProductListingLiveData() { fun clearProductListingLiveData() {
_productListingLiveData.postValue(ApiResult.Loading()) _productListingLiveData.postValue(ApiResult.Loading())
} }
// product view
var currentProductRemovedListener: (() -> Unit)? = null
var currentProductId: Int = -1
fun clearCurrentProductCallbacks(){
currentProductRemovedListener = null
currentProductId = -1
}
// cart // cart
val cartCountLivedata: LiveData<Int> val cartCountLivedata: LiveData<Int>
get() { get() {
@@ -211,4 +201,8 @@ class ShopViewModel: ViewModel() {
suspend fun addToCart(shopProduct: ShopProduct): ApiResult<Any> { suspend fun addToCart(shopProduct: ShopProduct): ApiResult<Any> {
return repository.addToCart(shopProduct) return repository.addToCart(shopProduct)
} }
suspend fun removeFromCart(id: Int): ApiResult<Double> {
return repository.removeCartItem(id)
}
} }

View File

@@ -12,7 +12,7 @@ import com.woka.utils.WokaBaseActivity
class CartActivity : WokaBaseActivity() { class CartActivity : WokaBaseActivity() {
companion object{ companion object{
const val EXTRA_REMOVED_CART_ITEMS = "extra_removed_cart_items" const val EXTRA_CURRENT_PRODUCT = "extra_current_product"
} }
private lateinit var binding: ActivityCartBinding private lateinit var binding: ActivityCartBinding

View File

@@ -3,14 +3,17 @@ package com.woka.shop.views
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.woka.R import com.woka.R
import com.woka.databinding.ActivityShopBinding import com.woka.databinding.ActivityShopBinding
import com.woka.shop.viewmodels.ShopViewModel import com.woka.shop.viewmodels.ShopViewModel
import com.woka.shop.views.fragments.shop.ShopFragment1 import com.woka.shop.views.CartActivity.Companion.EXTRA_CURRENT_PRODUCT
import com.woka.utils.WokaBaseActivity import com.woka.utils.WokaBaseActivity
import com.woka.utils.lightStatusBar
import com.woka.utils.setVisibility import com.woka.utils.setVisibility
class ShopActivity : WokaBaseActivity() { class ShopActivity : WokaBaseActivity() {
@@ -18,6 +21,8 @@ class ShopActivity : WokaBaseActivity() {
private lateinit var binding: ActivityShopBinding private lateinit var binding: ActivityShopBinding
private lateinit var viewModel: ShopViewModel private lateinit var viewModel: ShopViewModel
private lateinit var cartLauncher: ActivityResultLauncher<Intent>
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
@@ -32,16 +37,15 @@ class ShopActivity : WokaBaseActivity() {
viewModel = ViewModelProvider(this)[ShopViewModel::class.java] viewModel = ViewModelProvider(this)[ShopViewModel::class.java]
window.navigationBarColor = getColor(R.color.orders_bg) window.navigationBarColor = getColor(R.color.orders_bg)
window.lightStatusBar(false)
supportFragmentManager.beginTransaction()
.add(R.id.fcv_shop, ShopFragment1.newInstance())
.commit()
initViews() initViews()
clickEvents() clickEvents()
setObservers() setObservers()
registerLaunchers()
} }
private fun initViews() { private fun initViews() {
@@ -57,9 +61,18 @@ class ShopActivity : WokaBaseActivity() {
} }
cart.setOnClickListener { cart.setOnClickListener {
startActivity( cartLauncher.launch(Intent(this@ShopActivity, CartActivity::class.java).apply {
Intent(this@ShopActivity, CartActivity::class.java) putExtra(EXTRA_CURRENT_PRODUCT, viewModel.currentProductId)
) })
}
}
}
private fun registerLaunchers() {
cartLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
if (activityResult.resultCode == RESULT_OK) {
viewModel.currentProductRemovedListener?.invoke()
} }
} }
} }

View File

@@ -2,6 +2,7 @@ package com.woka.shop.views.fragments.cart
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -14,10 +15,10 @@ import com.woka.R
import com.woka.databinding.FragmentCartBinding import com.woka.databinding.FragmentCartBinding
import com.woka.networking.ApiResult import com.woka.networking.ApiResult
import com.woka.shop.adapters.CartAdapter import com.woka.shop.adapters.CartAdapter
import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.viewmodels.CartViewModel import com.woka.shop.viewmodels.CartViewModel
import com.woka.shop.views.CartActivity import com.woka.shop.views.CartActivity.Companion.EXTRA_CURRENT_PRODUCT
import com.woka.utils.ProgressView import com.woka.utils.ProgressView
import com.woka.utils.TAG
import com.woka.utils.hide import com.woka.utils.hide
import com.woka.utils.show import com.woka.utils.show
import com.woka.utils.toast import com.woka.utils.toast
@@ -32,6 +33,8 @@ class CartFragment: Fragment() {
private lateinit var progressDialog: ProgressView private lateinit var progressDialog: ProgressView
private var currentProductId: Int? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@@ -42,6 +45,9 @@ class CartFragment: Fragment() {
adapter = CartAdapter() adapter = CartAdapter()
progressDialog = ProgressView(requireContext()) progressDialog = ProgressView(requireContext())
currentProductId = requireActivity().intent.getIntExtra(EXTRA_CURRENT_PRODUCT, -1)
Log.d(TAG, "onCreateView: $currentProductId")
return binding.root return binding.root
} }
@@ -101,10 +107,9 @@ class CartFragment: Fragment() {
} }
} }
viewModel.removedProducts.add(ShopProduct(cartItem, false)) if (cartItem.id == currentProductId){
activity?.setResult(AppCompatActivity.RESULT_OK, Intent().apply { activity?.setResult(AppCompatActivity.RESULT_OK, Intent())
putParcelableArrayListExtra(CartActivity.EXTRA_REMOVED_CART_ITEMS, viewModel.removedProducts) }
})
} }
} }
} }

View File

@@ -1,14 +1,10 @@
package com.woka.shop.views.fragments.shop package com.woka.shop.views.fragments.shop
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.Html import android.text.Html
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -19,19 +15,24 @@ import com.woka.networking.ApiResult
import com.woka.shop.adapters.ProductImagesAdapter import com.woka.shop.adapters.ProductImagesAdapter
import com.woka.shop.models.productlisting.ShopProduct import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.viewmodels.ShopViewModel import com.woka.shop.viewmodels.ShopViewModel
import com.woka.shop.views.CartActivity
import com.woka.utils.ProgressView import com.woka.utils.ProgressView
import com.woka.utils.hide
import com.woka.utils.show
import com.woka.utils.toast import com.woka.utils.toast
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class ProductFragment private constructor( private const val ARG_PRODUCT_ID = "arg_product_id"
private val shopProduct: ShopProduct,
private val category: String class ProductFragment : Fragment() {
): Fragment() {
companion object { companion object {
@JvmStatic @JvmStatic
fun newInstance(shopProduct: ShopProduct, categoryName: String) = ProductFragment(shopProduct, categoryName) fun newInstance(productId: Int) =
ProductFragment().apply {
arguments = Bundle().apply {
putInt(ARG_PRODUCT_ID, productId)
}
}
} }
private lateinit var binding: FragmentProductBinding private lateinit var binding: FragmentProductBinding
@@ -39,7 +40,14 @@ class ProductFragment private constructor(
private lateinit var imageAdapter: ProductImagesAdapter private lateinit var imageAdapter: ProductImagesAdapter
private lateinit var progressView: ProgressView private lateinit var progressView: ProgressView
private lateinit var cartLauncher: ActivityResultLauncher<Intent> private var mShopProduct: ShopProduct? = null
private var productId: Int = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
productId = arguments?.getInt(ARG_PRODUCT_ID, -1)?:-1
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
@@ -49,11 +57,7 @@ class ProductFragment private constructor(
viewModel = ViewModelProvider(requireActivity())[ShopViewModel::class.java] viewModel = ViewModelProvider(requireActivity())[ShopViewModel::class.java]
progressView = ProgressView(requireContext(), getString(R.string.please_wait)) progressView = ProgressView(requireContext(), getString(R.string.please_wait))
val imageList = ArrayList<String>() imageAdapter = ProductImagesAdapter()
shopProduct.shop_image?.filterNotNull()?.let {
imageList.addAll(it)
}
imageAdapter = ProductImagesAdapter(imageList)
return binding.root return binding.root
} }
@@ -61,27 +65,83 @@ class ProductFragment private constructor(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
viewModel.currentProductId = productId
initViews() initViews()
clickEvents() clickEvents()
registerLaunchers() loadProductData()
setObservers()
}
override fun onDestroyView() {
super.onDestroyView()
viewModel.clearCurrentProductCallbacks()
} }
private fun initViews() { private fun initViews() {
binding.apply { binding.apply {
vpImages.adapter = imageAdapter vpImages.adapter = imageAdapter
TabLayoutMediator(tabLayout, vpImages) { _, _ -> }.attach() TabLayoutMediator(tabLayout, vpImages) { _, _ -> }.attach()
}
}
categoryName.text = category private fun clickEvents() {
binding.apply {
retryBtn.setOnClickListener {
loadProductData()
}
}
}
private fun loadProductData() {
lifecycleScope.launch {
binding.apply {
shimmer.show()
noData.hide()
productView.hide()
when (val response = viewModel.loadProductData(productId)) {
is ApiResult.Error -> {
shimmer.hide()
noData.show()
productView.hide()
}
is ApiResult.Loading -> {}
is ApiResult.Success -> {
response.data?.first()?.let {
shimmer.hide()
noData.hide()
productView.show()
displayProductData(it)
}
}
}
}
}
}
private fun displayProductData(shopProduct: ShopProduct) {
mShopProduct = shopProduct
binding.apply {
val imageList = ArrayList<String>()
shopProduct.shop_image?.filterNotNull()?.let {
imageList.addAll(it)
}
imageAdapter.submitList(imageList)
categoryName.text = shopProduct.category?.category_name
skuId.text = shopProduct.sku_id skuId.text = shopProduct.sku_id
price.text = shopProduct.product_price price.text = shopProduct.product_price
addToCart.text = if (shopProduct.added_to_cart == true) { addToCart.text = if (shopProduct.added_to_cart == true) {
getString(R.string.view_cart) getString(R.string.remove_from_cart)
} else { } else {
getString(R.string.add_to_cart) getString(R.string.add_to_cart)
} }
@@ -99,48 +159,56 @@ class ProductFragment private constructor(
Html.FROM_HTML_MODE_LEGACY Html.FROM_HTML_MODE_LEGACY
) )
} }
}
}
private fun clickEvents(){
binding.apply {
addToCart.setOnClickListener { addToCart.setOnClickListener {
if (shopProduct.added_to_cart == false){
lifecycleScope.launch { lifecycleScope.launch {
progressView.show() progressView.show()
if (shopProduct.added_to_cart == false) {
when (val response = viewModel.addToCart(shopProduct)) { when (val response = viewModel.addToCart(shopProduct)) {
is ApiResult.Error -> { is ApiResult.Error -> {
progressView.hide() progressView.hide()
toast(response.errorMessage) toast(response.errorMessage)
} }
is ApiResult.Loading -> {} is ApiResult.Loading -> {}
is ApiResult.Success -> { is ApiResult.Success -> {
progressView.hide() progressView.hide()
toast(response.message) toast(response.message)
shopProduct.added_to_cart = true shopProduct.added_to_cart = true
addToCart.text = getString(R.string.view_cart) addToCart.text = getString(R.string.remove_from_cart)
}
} }
} }
} else { } else {
activity?.let { when (val response = viewModel.removeFromCart(productId)) {
cartLauncher.launch(Intent(it, CartActivity::class.java)) is ApiResult.Error -> {
progressView.hide()
toast(response.errorMessage)
}
is ApiResult.Loading -> {}
is ApiResult.Success -> {
progressView.hide()
toast(response.message)
shopProduct.added_to_cart = false
addToCart.text = getString(R.string.add_to_cart)
}
}
} }
} }
} }
} }
} }
private fun registerLaunchers(){ private fun setObservers() {
cartLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ activityResult -> viewModel.currentProductRemovedListener = {
if (activityResult.resultCode == RESULT_OK){ binding.apply {
@Suppress("DEPRECATION") mShopProduct?.added_to_cart = mShopProduct?.added_to_cart == false
activityResult.data?.getParcelableArrayListExtra<ShopProduct>(CartActivity.EXTRA_REMOVED_CART_ITEMS)?.let {
viewModel.removeProductsFromCart(it) addToCart.text = if (mShopProduct?.added_to_cart == true) {
if (it.toSet().contains(shopProduct)){ getString(R.string.remove_from_cart)
binding.addToCart.text = if (shopProduct.added_to_cart == true){
getString(R.string.view_cart)
} else { } else {
getString(R.string.add_to_cart) getString(R.string.add_to_cart)
} }
@@ -148,5 +216,3 @@ class ProductFragment private constructor(
} }
} }
} }
}
}

View File

@@ -6,7 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.woka.R import androidx.navigation.fragment.findNavController
import com.woka.databinding.FragmentShop1Binding import com.woka.databinding.FragmentShop1Binding
import com.woka.networking.ApiResult import com.woka.networking.ApiResult
import com.woka.shop.adapters.CategoryAdapter import com.woka.shop.adapters.CategoryAdapter
@@ -15,7 +15,7 @@ import com.woka.shop.viewmodels.ShopViewModel
import com.woka.utils.hide import com.woka.utils.hide
import com.woka.utils.show import com.woka.utils.show
class ShopFragment1 private constructor(): Fragment() { class ShopFragment1 : Fragment() {
private lateinit var binding: FragmentShop1Binding private lateinit var binding: FragmentShop1Binding
private lateinit var viewModel: ShopViewModel private lateinit var viewModel: ShopViewModel
@@ -41,7 +41,8 @@ class ShopFragment1 private constructor(): Fragment() {
setObservers() setObservers()
if (!viewModel.superCategoryLiveData.isInitialized || if (!viewModel.superCategoryLiveData.isInitialized ||
viewModel.superCategoryLiveData.value !is ApiResult.Success) { viewModel.superCategoryLiveData.value !is ApiResult.Success
) {
viewModel.loadSuperCategories() viewModel.loadSuperCategories()
} }
@@ -60,10 +61,7 @@ class ShopFragment1 private constructor(): Fragment() {
} }
adapter.onCategoryClickListener = { adapter.onCategoryClickListener = {
parentFragmentManager.beginTransaction() findNavController().navigate(ShopFragment1Directions.actionShopFragment1ToShopFragment2(it))
.replace(R.id.fcv_shop, ShopFragment2.newInstance("${it.id}"))
.addToBackStack(null)
.commitAllowingStateLoss()
} }
} }
} }

View File

@@ -6,7 +6,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.woka.R import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.woka.databinding.FragmentShop2Binding import com.woka.databinding.FragmentShop2Binding
import com.woka.networking.ApiResult import com.woka.networking.ApiResult
import com.woka.shop.adapters.CategoryAdapter import com.woka.shop.adapters.CategoryAdapter
@@ -15,12 +16,18 @@ import com.woka.shop.viewmodels.ShopViewModel
import com.woka.utils.hide import com.woka.utils.hide
import com.woka.utils.show import com.woka.utils.show
class ShopFragment2 private constructor(private val superCategoryId: String): Fragment() { class ShopFragment2 : Fragment() {
private lateinit var binding: FragmentShop2Binding private lateinit var binding: FragmentShop2Binding
private lateinit var viewModel: ShopViewModel private lateinit var viewModel: ShopViewModel
private lateinit var adapter: CategoryAdapter private lateinit var adapter: CategoryAdapter
private val args: ShopFragment2Args by navArgs()
private val superCategoryId: String by lazy {
"${args.superCategoryId}"
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@@ -61,10 +68,12 @@ class ShopFragment2 private constructor(private val superCategoryId: String): Fr
} }
adapter.onCategoryClickListener = { adapter.onCategoryClickListener = {
parentFragmentManager.beginTransaction() findNavController().navigate(
.replace(R.id.fcv_shop, ShopFragment3.newInstance(superCategoryId, "${it.id}", "${it.title}")) ShopFragment2Directions.actionShopFragment2ToShopFragment3(
.addToBackStack(null) superCategoryId,
.commitAllowingStateLoss() "$it"
)
)
} }
} }
} }
@@ -106,9 +115,4 @@ class ShopFragment2 private constructor(private val superCategoryId: String): Fr
} }
} }
} }
companion object {
@JvmStatic
fun newInstance(superCategoryId: String) = ShopFragment2(superCategoryId)
}
} }

View File

@@ -6,6 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.navArgs
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.woka.R import com.woka.R
import com.woka.databinding.FragmentShop3Binding import com.woka.databinding.FragmentShop3Binding
@@ -16,22 +17,17 @@ import com.woka.utils.hide
import com.woka.utils.setVisibility import com.woka.utils.setVisibility
import com.woka.utils.show import com.woka.utils.show
class ShopFragment3 private constructor( class ShopFragment3 : Fragment(), TabLayout.OnTabSelectedListener {
private val superCategoryId: String,
private val categoryId: String,
private val categoryName: String
) : Fragment(), TabLayout.OnTabSelectedListener {
companion object {
@JvmStatic
fun newInstance(superCategoryId: String, categoryId: String, categoryName: String) =
ShopFragment3(superCategoryId, categoryId, categoryName)
}
private lateinit var binding: FragmentShop3Binding private lateinit var binding: FragmentShop3Binding
private lateinit var viewModel: ShopViewModel private lateinit var viewModel: ShopViewModel
private lateinit var productAdapter: ShopProductAdapter private lateinit var productAdapter: ShopProductAdapter
private val args: ShopFragment3Args by navArgs()
private val superCategoryId: String by lazy { args.superCategoryId }
private val categoryId: String by lazy { args.categoryId }
private var loadMoreProducts = false private var loadMoreProducts = false
override fun onCreateView( override fun onCreateView(
@@ -80,14 +76,11 @@ class ShopFragment3 private constructor(
prodLoadMoreBtn.setOnClickListener { prodLoadMoreBtn.setOnClickListener {
loadMoreProducts = true loadMoreProducts = true
val subCategoryId = categoryTabs.getTabAt(categoryTabs.selectedTabPosition)?.tag?.toString() val subCategoryId = categoryTabs.getTabAt(categoryTabs.selectedTabPosition)?.tag?.toString()
viewModel.loadMoreEpisodes(superCategoryId, categoryId, subCategoryId) viewModel.loadMoreProducts(superCategoryId, categoryId, subCategoryId)
} }
productAdapter.onProductClicked = { productAdapter.onProductClicked = {
parentFragmentManager.beginTransaction()
.add(R.id.fcv_shop, ProductFragment.newInstance(it, categoryName))
.addToBackStack(null)
.commit()
} }
} }
} }

View File

@@ -102,15 +102,11 @@
</RelativeLayout> </RelativeLayout>
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/fcv_shop" android:id="@+id/fc_shop"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:defaultNavHost="true"
android:background="@color/white" app:navGraph="@navigation/nav_graph_shop" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"
/>
</LinearLayout> </LinearLayout>

View File

@@ -263,24 +263,42 @@
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<TextView <LinearLayout
android:id="@+id/no_data" android:id="@+id/no_data"
android:visibility="gone" android:visibility="gone"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:contentDescription="@string/image"
android:src="@drawable/img_support"
/>
<TextView
android:id="@+id/no_data_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_favorites_added" android:text="@string/no_favorites_added"
android:fontFamily="@font/exo_2_bold" android:fontFamily="@font/exo_2_bold"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_14ssp" android:textSize="@dimen/_14ssp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/> />
</LinearLayout>
<ProgressBar <ProgressBar
android:id="@+id/progress_bar" android:id="@+id/progress_bar"
android:visibility="gone" android:visibility="gone"

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout 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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/orders_bg" android:background="@color/orders_bg"
tools:context=".shop.views.fragments.shop.ProductFragment"> tools:context=".shop.views.fragments.shop.ProductFragment">
@@ -12,40 +12,162 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
app:layout_constraintGuide_percent="0.7" app:layout_constraintGuide_percent="0.7" />
/>
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:contentDescription="@string/image" android:contentDescription="@string/image"
android:src="@drawable/img_my_orders_ng"
android:scaleType="fitXY" android:scaleType="fitXY"
android:src="@drawable/img_my_orders_ng"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/g1" app:layout_constraintTop_toBottomOf="@id/g1" />
/>
<androidx.core.widget.NestedScrollView <com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/shimmer"
android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
app:shimmer_auto_start="true"
app:shimmer_duration="1500"
app:shimmer_highlight_alpha="0.5">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingHorizontal="15dp" android:layout_margin="15dp"
android:paddingVertical="10dp"
android:orientation="vertical"> android:orientation="vertical">
<View
android:layout_width="300dp"
android:layout_height="20dp"
android:background="@color/black_50" />
<View
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginTop="15dp"
android:background="@color/black_50" />
<View
android:layout_width="250dp"
android:layout_height="20dp"
android:layout_marginTop="15dp"
android:background="@color/black_50" />
<View
android:layout_width="200dp"
android:layout_height="20dp"
android:layout_marginTop="15dp"
android:background="@color/black_50" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
>
<View
android:layout_width="100dp"
android:layout_height="25dp"
android:layout_marginTop="15dp"
android:layout_centerVertical="true"
android:background="@drawable/round_bg_5"
android:backgroundTint="@color/black_50" />
<View
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_marginTop="15dp"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:backgroundTint="@color/black_50"
android:background="@drawable/round_25" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="15dp"
android:background="@color/black_50" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<LinearLayout
android:id="@+id/no_data"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:contentDescription="@string/image"
android:src="@drawable/img_support"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/something_went_wrong"
android:fontFamily="@font/exo_2_bold"
android:textColor="@color/color_primary"
android:textSize="@dimen/_14ssp"
android:layout_marginTop="10dp"
/>
<TextView
android:id="@+id/retry_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/retry_underline"
android:fontFamily="@font/exo_2_bold"
android:textColor="@color/color_primary"
android:textSize="@dimen/_12ssp"
android:padding="5dp"
/>
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/product_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="15dp"
android:paddingVertical="10dp">
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:text="Some title of the product"
android:fontFamily="@font/exo_2_bold" android:fontFamily="@font/exo_2_bold"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_14ssp" android:textSize="@dimen/_14ssp"
tools:text="Some title of the product"
/> />
@@ -53,25 +175,23 @@
android:id="@+id/vp_images" android:id="@+id/vp_images"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/_120sdp" android:layout_height="@dimen/_120sdp"
android:layout_marginTop="15dp" android:layout_marginTop="15dp" />
/>
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout" android:id="@+id/tab_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:layout_marginHorizontal="15dp"
android:background="@android:color/transparent"
app:tabBackground="@drawable/product_indicator_selector" app:tabBackground="@drawable/product_indicator_selector"
app:tabGravity="center" app:tabGravity="center"
app:tabIndicatorHeight="0dp" app:tabIndicatorHeight="0dp"
app:tabPaddingEnd="10dp" app:tabPaddingEnd="10dp"
app:tabPaddingStart="10dp" app:tabPaddingStart="10dp"
app:tabRippleColor="@android:color/transparent"
android:background="@android:color/transparent" app:tabRippleColor="@android:color/transparent" />
android:layout_marginHorizontal="15dp"
/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -82,8 +202,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/category_name"
android:fontFamily="@font/exo_2_bold" android:fontFamily="@font/exo_2_bold"
android:text="@string/category_name"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_12ssp" android:textSize="@dimen/_12ssp"
@@ -94,12 +214,12 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:text="This is a random text for preview" android:layout_marginStart="5dp"
android:fontFamily="@font/exo_2" android:fontFamily="@font/exo_2"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_12ssp" android:textSize="@dimen/_12ssp"
android:layout_marginStart="5dp" tools:text="This is a random text for preview"
/> />
@@ -115,8 +235,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/sku_id"
android:fontFamily="@font/exo_2_bold" android:fontFamily="@font/exo_2_bold"
android:text="@string/sku_id"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_12ssp" android:textSize="@dimen/_12ssp"
@@ -127,12 +247,12 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:text="This is a random text for preview" android:layout_marginStart="5dp"
android:fontFamily="@font/exo_2" android:fontFamily="@font/exo_2"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_12ssp" android:textSize="@dimen/_12ssp"
android:layout_marginStart="5dp" tools:text="This is a random text for preview"
/> />
@@ -148,17 +268,17 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:text="$ 200"
android:fontFamily="@font/exo_2_bold" android:fontFamily="@font/exo_2_bold"
android:maxLines="1"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_16ssp" android:textSize="@dimen/_16ssp"
android:maxLines="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/addToCart"
app:layout_constraintTop_toTopOf="@id/addToCart"
app:layout_constraintBottom_toBottomOf="@id/addToCart" app:layout_constraintBottom_toBottomOf="@id/addToCart"
app:layout_constraintEnd_toStartOf="@id/addToCart"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/addToCart"
tools:text="$ 200"
/> />
<Button <Button
@@ -166,24 +286,24 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/add_to_cart"
android:fontFamily="@font/exo_2_extrabold"
android:textColor="@color/white"
android:textSize="@dimen/_10ssp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@drawable/round_bg_25" android:background="@drawable/round_bg_25"
android:backgroundTint="@color/color_primary" android:backgroundTint="@color/color_primary"
android:drawableStart="@drawable/ic_cart_filled" android:drawableStart="@drawable/ic_cart_filled"
android:drawablePadding="15dp" android:drawablePadding="15dp"
android:paddingEnd="20dp" android:fontFamily="@font/exo_2_extrabold"
android:paddingStart="15dp"
android:paddingVertical="5dp" android:paddingVertical="5dp"
android:paddingStart="15dp"
android:paddingEnd="20dp"
android:text="@string/add_to_cart"
android:textColor="@color/white"
android:textSize="@dimen/_10ssp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
/> />
@@ -194,11 +314,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:fontFamily="@font/exo_2" android:fontFamily="@font/exo_2"
android:textColor="@color/color_primary" android:textColor="@color/color_primary"
android:textSize="@dimen/_12ssp"
android:layout_marginTop="15dp" android:textSize="@dimen/_12ssp"
/> />

View File

@@ -5,7 +5,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/orders_bg" android:background="@color/orders_bg"
tools:context=".shop.views.fragments.shop.ShopFragment2"> tools:context=".shop.views.fragments.shop.ShopFragment1">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_super_category" android:id="@+id/rv_super_category"

View File

@@ -5,7 +5,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/orders_bg" android:background="@color/orders_bg"
tools:context=".shop.views.fragments.shop.ShopFragment2"> tools:context=".shop.views.fragments.shop.ShopFragment3">
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/nav_graph_shop"
app:startDestination="@id/shopFragment1">
<fragment
android:id="@+id/shopFragment1"
android:name="com.woka.shop.views.fragments.shop.ShopFragment1"
android:label="fragment_shop1"
tools:layout="@layout/fragment_shop1" >
<action
android:id="@+id/action_shopFragment1_to_shopFragment2"
app:destination="@id/shopFragment2" />
</fragment>
<fragment
android:id="@+id/shopFragment2"
android:name="com.woka.shop.views.fragments.shop.ShopFragment2"
android:label="fragment_shop2"
tools:layout="@layout/fragment_shop2" >
<action
android:id="@+id/action_shopFragment2_to_shopFragment3"
app:destination="@id/shopFragment3" />
<argument
android:name="superCategoryId"
app:argType="integer"
android:defaultValue="-1" />
</fragment>
<fragment
android:id="@+id/shopFragment3"
android:name="com.woka.shop.views.fragments.shop.ShopFragment3"
android:label="fragment_shop3"
tools:layout="@layout/fragment_shop3" >
<argument
android:name="superCategoryId"
app:argType="string" />
<argument
android:name="categoryId"
app:argType="string" />
</fragment>
</navigation>

View File

@@ -281,5 +281,6 @@
<string name="category_name">Category Name :</string> <string name="category_name">Category Name :</string>
<string name="sku_id">SKU Id :</string> <string name="sku_id">SKU Id :</string>
<string name="add_to_cart">ADD TO CART</string> <string name="add_to_cart">ADD TO CART</string>
<string name="remove_from_cart">REMOVE</string>
<string name="view_cart">view cart</string> <string name="view_cart">view cart</string>
</resources> </resources>

View File

@@ -2,4 +2,5 @@
plugins { plugins {
alias(libs.plugins.androidApplication) apply false alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false alias(libs.plugins.jetbrainsKotlinAndroid) apply false
alias(libs.plugins.navigationSafeArgs) apply false
} }

View File

@@ -11,6 +11,7 @@ activity = "1.8.0"
constraintlayout = "2.1.4" constraintlayout = "2.1.4"
navigationFragmentKtx = "2.7.7" navigationFragmentKtx = "2.7.7"
navigationUiKtx = "2.7.7" navigationUiKtx = "2.7.7"
navigationSafeArgs = "2.7.7"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -27,4 +28,4 @@ androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation
[plugins] [plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" } androidApplication = { id = "com.android.application", version.ref = "agp" }
jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
navigationSafeArgs = {id = "androidx.navigation.safeargs.kotlin", version.ref = "navigationSafeArgs"}