This commit is contained in:
2023-11-13 14:23:33 +03:00
commit 4d842a9b42
148 changed files with 5990 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
/build
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+115
View File
@@ -0,0 +1,115 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
id("com.google.devtools.ksp") version "1.9.10-1.0.13"
id("kotlin-kapt")
id("androidx.navigation.safeargs.kotlin")
}
android {
namespace = "com.yaros.sweetshopviki"
compileSdk = 34
defaultConfig {
applicationId = "com.yaros.sweetshopviki"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
kotlin {
jvmToolchain(8)
}
buildFeatures {
compose = true
viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.3"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.0")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation("com.google.devtools.ksp:symbol-processing-api:1.9.10-1.0.13")
implementation(kotlin("stdlib-jdk8"))
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.4")
implementation("androidx.navigation:navigation-ui-ktx:2.7.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1")
implementation(platform("com.google.firebase:firebase-bom:32.5.0"))
implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.firebaseui:firebase-ui-auth:7.2.0")
implementation("com.google.firebase:firebase-firestore-ktx")
implementation("com.google.firebase:firebase-analytics")
implementation("com.facebook.shimmer:shimmer:0.5.0")
implementation("com.squareup.picasso:picasso:2.71828")
implementation("com.github.Zhuinden:fragmentviewbindingdelegate-kt:1.0.2")
implementation("nl.joery.animatedbottombar:library:1.1.0")
implementation("com.github.Spikeysanju:MotionToast:1.4")
implementation("com.github.ibrahimsn98:SmoothBottomBar:1.7.9")
implementation("com.apachat:loadingbutton-android:1.0.11")
implementation("com.google.android.material:material:1.10.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("com.google.code.gson:gson:2.9.1")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("androidx.room:room-runtime:2.6.0")
implementation("androidx.room:room-ktx:2.6.0")
ksp("androidx.room:room-compiler:2.6.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
}
+30
View File
@@ -0,0 +1,30 @@
{
"project_info": {
"project_number": "196968989683",
"firebase_url": "https://sweetshopviki-default-rtdb.europe-west1.firebasedatabase.app",
"project_id": "sweetshopviki",
"storage_bucket": "sweetshopviki.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:196968989683:android:40a8cee7ccf184d17e0886",
"android_client_info": {
"package_name": "com.yaros.sweetshopviki"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyBO4bIOLwDFly-tUmI9mbPtW37RDmf3FEQ"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,24 @@
package com.yaros.sweetshopviki
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.yaros.sweetshopviki", appContext.packageName)
}
}
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.yaros.sweetshopviki">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MaterialComponents"
tools:targetApi="31">
<activity
android:name=".ui.SplashActivity"
android:theme="@style/Theme.AppCompat"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.login.LoginActivity"
android:exported="false" />
<activity
android:name=".ui.MainActivity"
android:exported="false" />
</application>
</manifest>
@@ -0,0 +1,65 @@
package com.yaros.sweetshopviki.common
import android.app.Activity
import android.content.Context
import android.view.Gravity
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import com.squareup.picasso.Picasso
import com.yaros.sweetshopviki.R
fun Double.formatPrice(): String {
return String.format("%.2f", this) + ""
}
fun Float.formatPrice(): String {
return String.format("%.2f", this) + ""
}
fun ImageView.loadImage(url: String?) {
Picasso.get()
.load("https://liwapos.com/samba.mobil/Content/$url")
.placeholder(R.drawable.loading)
.error(R.drawable.error)
.into(this)
}
fun getPaymentImages(): ArrayList<Int> {
return arrayListOf(R.drawable.ic_cash, R.drawable.ic_bank_cards)
}
fun Context.getPaymentNames(): ArrayList<String> {
return arrayListOf(this.getString(R.string.cash), this.getString(R.string.credit_card))
}
fun View.visible() {
this.visibility = View.VISIBLE
}
fun View.gone() {
this.visibility = View.GONE
}
fun Toast.showCustomToast(toastText: String, activity: Activity) {
val layout = activity.layoutInflater.inflate(
R.layout.custom_toast,
activity.findViewById(R.id.toast_layout_root)
)
val text =
layout.findViewById<View>(R.id.text) as TextView
text.text = toastText
this.apply {
setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL, 0, 0)
duration = Toast.LENGTH_SHORT
view = layout
show()
}
}
@@ -0,0 +1,15 @@
package com.yaros.sweetshopviki.common.utils
import com.yaros.sweetshopviki.data.retrofit.DAOInterface
import com.yaros.sweetshopviki.data.retrofit.RetrofitClient
class ApiUtils {
companion object {
private const val BASE_URL = "https://my-json-server.typicode.com/YarikHumster/SweetShopViki/"
fun getInterfaceDAO(): DAOInterface {
return RetrofitClient.getClient(BASE_URL).create(DAOInterface::class.java)
}
}
}
@@ -0,0 +1,11 @@
package com.yaros.sweetshopviki.data.models
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import java.io.Serializable
data class Categories (
@SerializedName("id") @Expose var id: Int,
@SerializedName("name") @Expose var name: String,
@SerializedName("imagePath") @Expose var imagePath: String
): Serializable
@@ -0,0 +1,15 @@
package com.yaros.sweetshopviki.data.models
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import java.io.Serializable
data class Product (
@SerializedName("Name") @Expose var name: String?,
@SerializedName("ImagePath") @Expose var imagePath: String?,
@SerializedName("Price") @Expose var price: Double?,
@SerializedName("MenuItemId") @Expose var menuItemId: Int?,
@SerializedName("GroupName") @Expose var groupName: String?,
@SerializedName("CustomTags") @Expose var customTags: String?,
@SerializedName("Expr1") @Expose var portion: String?
): Serializable
@@ -0,0 +1,26 @@
package com.yaros.sweetshopviki.data.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "productsbasketdatabase")
data class ProductsBasketRoomModel(
@PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "id")
var productId: Int = 0,
@ColumnInfo(name = "productName")
var productName: String?,
@ColumnInfo(name = "productCount")
var productCount: Int = 1,
@ColumnInfo(name = "productPrice")
var productPrice: Double?,
@ColumnInfo(name = "productImage")
var productImage: String?
)
@@ -0,0 +1,7 @@
package com.yaros.sweetshopviki.data.models
data class UserModel (
val email: String?,
val phoneNumber: String?,
val userName: String?,
)
@@ -0,0 +1,135 @@
package com.yaros.sweetshopviki.data.repo
import android.content.Context
import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.yaros.sweetshopviki.common.utils.ApiUtils
import com.yaros.sweetshopviki.data.models.Categories
import com.yaros.sweetshopviki.data.models.Product
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.data.retrofit.DAOInterface
import com.yaros.sweetshopviki.data.room.ProductsBasketDAOInterface
import com.yaros.sweetshopviki.data.room.ProductsBasketRoomDatabase
import kotlinx.coroutines.runBlocking
class Repository(context: Context) {
enum class LOADING {
LOADING, DONE, ERROR
}
val categoriesList = MutableLiveData<List<Categories>>()
val productList = MutableLiveData<List<Product>>()
val searchList = MutableLiveData<List<Product>>()
val basketList = MutableLiveData<List<ProductsBasketRoomModel>>()
val isLoading = MutableLiveData<LOADING>()
val basketTotalAmount = MutableLiveData<Double>()
private val dif: DAOInterface = ApiUtils.getInterfaceDAO()
private val basketDif: ProductsBasketDAOInterface? =
ProductsBasketRoomDatabase.productsBasketRoomDatabase(context)?.productsBasketDAOInterface()
suspend fun getCategories() {
try {
isLoading.value = LOADING.LOADING
val response = dif.getCategories()
if (response.isSuccessful) {
val tempList = response.body()
categoriesList.value = tempList!!
isLoading.value = LOADING.DONE
} else {
isLoading.value = LOADING.ERROR
}
} catch (t: Throwable) {
t.localizedMessage?.toString()?.let { Log.e("getCategories", it) }
isLoading.value = LOADING.ERROR
}
}
suspend fun getProducts(categoryId: Int) {
try {
isLoading.value = LOADING.LOADING
val response = dif.getProducts(categoryId)
if (response.isSuccessful) {
val tempList = response.body()
productList.value = tempList!!
isLoading.value = LOADING.DONE
} else {
isLoading.value = LOADING.ERROR
}
} catch (t: Throwable) {
t.localizedMessage?.toString()?.let { Log.e("getCategories", it) }
isLoading.value = LOADING.ERROR
}
}
suspend fun getSearch() {
try {
isLoading.value = LOADING.LOADING
val response = dif.getSearch()
if (response.isSuccessful) {
val tempList = response.body()
searchList.value = tempList!!
isLoading.value = LOADING.DONE
} else {
isLoading.value = LOADING.ERROR
}
} catch (t: Throwable) {
t.localizedMessage?.toString()?.let { Log.e("getCategories", it) }
isLoading.value = LOADING.ERROR
}
}
fun getBasket() = runBlocking {
isLoading.value = LOADING.LOADING
basketDif?.getProductsBasket()?.let {
basketList.value = it
isLoading.value = LOADING.DONE
} ?: run {
isLoading.value = LOADING.DONE
}
}
fun getBasketTotalAmount() = runBlocking {
if (basketDif?.getProductsBasketTotalAmount() != null) {
basketTotalAmount.value = basketDif.getProductsBasketTotalAmount()
} else {
basketTotalAmount.value = 0.00
}
}
suspend fun addBookToBasket(productModel: ProductsBasketRoomModel) {
val productFromDatabase = basketDif?.getProductById(productModel.productId)
if (productFromDatabase != null) {
val productCount = productFromDatabase.productCount + productModel.productCount
val productPrice =
(productFromDatabase.productPrice?.div(productFromDatabase.productCount))?.times(
productCount
)
basketDif?.updateProductBasket(productModel.productId, productCount, productPrice)
} else {
basketDif?.addProductBasket(productModel)
}
}
suspend fun deleteBookFromBasket(productId: Int) {
basketDif?.deleteProductWithId(productId)
}
suspend fun clearBasket() {
basketDif?.clearBasket()
}
}
@@ -0,0 +1,105 @@
package com.yaros.sweetshopviki.data.repo
import android.content.ContentValues
import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.google.firebase.auth.ktx.auth
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.yaros.sweetshopviki.data.models.UserModel
class UserRepository {
enum class LOADING {
LOADING, DONE, ERROR
}
var isSignIn = MutableLiveData<Boolean>()
var isSignUp = MutableLiveData<Boolean>()
var userInfo = MutableLiveData<UserModel>()
var isLoading = MutableLiveData<LOADING>()
private var auth = Firebase.auth
private val db = Firebase.firestore
fun signIn(eMail: String, password: String) {
isLoading.value = LOADING.LOADING
auth.signInWithEmailAndPassword(eMail, password).addOnCompleteListener { task ->
if (task.isSuccessful) {
isLoading.value = LOADING.DONE
isSignIn.value = true
Log.d("SIGN_IN", "SUCCESS")
} else {
isLoading.value = LOADING.ERROR
isSignIn.value = false
Log.w("SIGN_IN", "FAILURE", task.exception)
}
}
}
fun signUp(eMail: String, password: String, phoneNumber: String, userName: String) {
isLoading.value = LOADING.LOADING
auth.createUserWithEmailAndPassword(eMail, password).addOnCompleteListener { task ->
if (task.isSuccessful) {
val currentUser = auth.currentUser
currentUser?.let { fbUser ->
val user = hashMapOf(
"id" to fbUser.uid,
"email" to eMail,
"phonenumber" to phoneNumber,
"username" to userName
)
db.collection("users").document(fbUser.uid)
.set(user)
.addOnSuccessListener {
isSignUp.value = true
isLoading.value = LOADING.DONE
Log.d("SIGN_UP", "SUCCESS")
}
.addOnFailureListener { e ->
isSignUp.value = false
isLoading.value = LOADING.ERROR
Log.w("SIGN_UP", "FAILURE", e)
}
}
isLoading.value = LOADING.DONE
} else {
isSignUp.value = false
isLoading.value = LOADING.ERROR
Log.w("SIGN_UP", "FAILURE", task.exception)
}
}
}
fun getUserInfo() {
isLoading.value = LOADING.LOADING
auth.currentUser?.let { user ->
val docRef = db.collection("users").document(user.uid)
docRef.get()
.addOnSuccessListener { document ->
document?.let {
userInfo.value = UserModel(
user.email,
document.get("phonenumber") as String,
document.get("username") as String
)
isLoading.value = LOADING.DONE
}
}
.addOnFailureListener { exception ->
Log.d(ContentValues.TAG, "get failed with ", exception)
isLoading.value = LOADING.ERROR
}
}
}
fun signOut() {
isLoading.value = LOADING.LOADING
auth.signOut()
isLoading.value = LOADING.DONE
}
}
@@ -0,0 +1,18 @@
package com.yaros.sweetshopviki.data.retrofit
import com.yaros.sweetshopviki.data.models.Categories
import com.yaros.sweetshopviki.data.models.Product
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Path
interface DAOInterface {
@GET("JsonCategories")
suspend fun getCategories(): Response<List<Categories>>
@GET("JsonItems/{id}")
suspend fun getProducts(@Path("id") id: Int): Response<List<Product>>
@GET("JsonSearch")
suspend fun getSearch(): Response<List<Product>>
}
@@ -0,0 +1,15 @@
package com.yaros.sweetshopviki.data.retrofit
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class RetrofitClient {
companion object {
fun getClient(baseUrl: String): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
}
@@ -0,0 +1,30 @@
package com.yaros.sweetshopviki.data.room
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
@Dao
interface ProductsBasketDAOInterface {
@Insert
suspend fun addProductBasket(productsBasketRoomModel: ProductsBasketRoomModel)
@Query("SELECT * FROM productsbasketdatabase")
suspend fun getProductsBasket(): List<ProductsBasketRoomModel>?
@Query("SELECT Sum(ProductPrice) FROM productsbasketdatabase")
suspend fun getProductsBasketTotalAmount(): Double?
@Query("SELECT * FROM productsbasketdatabase WHERE id = :productId LIMIT 1")
suspend fun getProductById(productId: Int): ProductsBasketRoomModel?
@Query("DELETE FROM productsbasketdatabase WHERE id = :idInput")
suspend fun deleteProductWithId(idInput: Int)
@Query("DELETE FROM productsbasketdatabase")
suspend fun clearBasket()
@Query("UPDATE productsbasketdatabase SET productCount=:productCount, productPrice=:productPrice WHERE id = :productId")
suspend fun updateProductBasket(productId: Int, productCount: Int, productPrice: Double?)
}
@@ -0,0 +1,33 @@
package com.yaros.sweetshopviki.data.room
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
@Database(entities = [ProductsBasketRoomModel::class], version = 1, exportSchema = false)
abstract class ProductsBasketRoomDatabase : RoomDatabase() {
abstract fun productsBasketDAOInterface(): ProductsBasketDAOInterface
companion object {
private var instance: ProductsBasketRoomDatabase? = null
fun productsBasketRoomDatabase(context: Context): ProductsBasketRoomDatabase? {
if (instance == null) {
synchronized(ProductsBasketRoomDatabase::class) {
instance = Room.databaseBuilder(
context,
ProductsBasketRoomDatabase::class.java,
"productsbasketdatabase.db"
)
.build()
}
}
return instance
}
}
}
@@ -0,0 +1,34 @@
package com.yaros.sweetshopviki.ui
import android.os.Bundle
import android.widget.PopupMenu
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupSmoothBottomMenu()
}
private fun setupSmoothBottomMenu() {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
val popupMenu = PopupMenu(this, null)
popupMenu.inflate(R.menu.menu)
val menu = popupMenu.menu
binding.navigationView.setupWithNavController(menu, navHostFragment.navController)
}
}
@@ -0,0 +1,28 @@
package com.yaros.sweetshopviki.ui
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.yaros.sweetshopviki.databinding.ActivitySplashBinding
import com.yaros.sweetshopviki.ui.login.LoginActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@SuppressLint("CustomSplashScreen")
class SplashActivity : AppCompatActivity() {
private lateinit var binding: ActivitySplashBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater)
setContentView(binding.root)
CoroutineScope(Dispatchers.Main).launch {
val intent = Intent(this@SplashActivity, LoginActivity::class.java)
startActivity(intent)
finish()
}
}
}
@@ -0,0 +1,56 @@
package com.yaros.sweetshopviki.ui.basket
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.recyclerview.widget.RecyclerView
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.databinding.BasketItemBinding
class BasketAdapter (private var basketList: ArrayList<ProductsBasketRoomModel>) :
RecyclerView.Adapter<BasketAdapter.ProductsViewHolder>() {
class ProductsViewHolder(val productCardBinding: BasketItemBinding) :
RecyclerView.ViewHolder(productCardBinding.root)
var onDeleteClick: (Int) -> Unit = {}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ProductsViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val basketItemBinding = BasketItemBinding.inflate(layoutInflater, parent, false)
return ProductsViewHolder(basketItemBinding)
}
override fun onBindViewHolder(holder: ProductsViewHolder, position: Int) {
val product = basketList[position]
holder.productCardBinding.apply {
productText.text = product.productName
productCount.text = product.productCount.toString() + " X"
productPrice.text = product.productPrice?.formatPrice()
deleteBasketProduct.setOnClickListener {
onDeleteClick(product.productId)
basketList.removeAt(position)
notifyItemRemoved(position)
notifyItemRangeChanged(
position,
itemCount
)
}
}
holder.productCardBinding.root.animation =
AnimationUtils.loadAnimation(holder.itemView.context, R.anim.recyclerview_anim)
}
override fun getItemCount(): Int {
return basketList.size
}
}
@@ -0,0 +1,138 @@
package com.yaros.sweetshopviki.ui.basket
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.common.gone
import com.yaros.sweetshopviki.common.visible
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.data.repo.Repository
import com.yaros.sweetshopviki.databinding.FragmentBasketBinding
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
class BasketFragment : Fragment(R.layout.fragment_basket) {
private val binding by viewBinding(FragmentBasketBinding::bind)
private val viewModel by lazy { BasketViewModel(requireContext()) }
private var basketAmount: Double = 0.0
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as AppCompatActivity?)!!.supportActionBar!!.title =
resources.getString(R.string.basket)
(activity as AppCompatActivity?)!!.supportActionBar!!.setDisplayHomeAsUpEnabled(false)
binding.apply {
viewModel.apply {
getBasket()
initObservers()
}
}
initToolbarMenu()
}
private fun initToolbarMenu() {
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.search, menu)
val item = menu.findItem(R.id.action_search)
item.isVisible = false
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return false
}
}, viewLifecycleOwner, Lifecycle.State.RESUMED)
}
private fun initObservers() {
binding.apply {
viewModel.apply {
isLoading.observe(viewLifecycleOwner) {
when (it!!) {
Repository.LOADING.LOADING -> {
shimmerLayout.startShimmer()
}
Repository.LOADING.DONE -> {
shimmerLayout.apply {
gone()
stopShimmer()
}
basketRecyclerView.visible()
}
Repository.LOADING.ERROR -> {
shimmerLayout.apply {
stopShimmer()
gone()
}
basketRecyclerView.visible()
}
}
}
basketTotalAmount.observe(viewLifecycleOwner) { basketTotalAmount ->
if (basketTotalAmount > 0.00) {
totalAmount.text =
basketTotalAmount.formatPrice()
approveLayout.visible()
basketRecyclerView.visible()
emptyLayout.gone()
} else {
approveLayout.gone()
basketRecyclerView.gone()
emptyLayout.visible()
}
basketAmount = basketTotalAmount
}
basketList.observe(viewLifecycleOwner) { basketList ->
val basketAdapter =
BasketAdapter(basketList as ArrayList<ProductsBasketRoomModel>)
basketRecyclerView.adapter = basketAdapter
basketAdapter.onDeleteClick = ::onDeleteClick
if (basketList.isNotEmpty()) {
approveLayout.visible()
} else {
approveLayout.gone()
}
}
basketRecyclerView.layoutManager = LinearLayoutManager(context)
basketRecyclerView.setHasFixedSize(true)
addOrder.setOnClickListener { findNavController().navigate(BasketFragmentDirections.actionBasketFragmentToCategoriesFragment()) }
approveBasket.setOnClickListener {
findNavController().navigate(
BasketFragmentDirections.actionBasketFragmentToPaymentFragment(basketAmount.toFloat())
)
}
}
}
}
private fun onDeleteClick(productId: Int) {
viewModel.deleteProductFromBasket(productId)
}
}
@@ -0,0 +1,42 @@
package com.yaros.sweetshopviki.ui.basket
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.data.repo.Repository
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class BasketViewModel(context: Context) : ViewModel() {
private val repository = Repository(context)
var basketList: LiveData<List<ProductsBasketRoomModel>> = repository.basketList
var basketTotalAmount: LiveData<Double> = repository.basketTotalAmount
var isLoading: LiveData<Repository.LOADING> = repository.isLoading
fun getBasket() {
viewModelScope.launch {
// Bottom Navigation Bar is lagging if don't add delay
delay(500)
repository.getBasket()
getBasketTotalAmount()
}
}
fun deleteProductFromBasket(productId: Int) {
viewModelScope.launch {
repository.deleteBookFromBasket(productId)
getBasketTotalAmount()
}
}
private fun getBasketTotalAmount() {
viewModelScope.launch {
repository.getBasketTotalAmount()
}
}
}
@@ -0,0 +1,48 @@
package com.yaros.sweetshopviki.ui.category
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.recyclerview.widget.RecyclerView
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.loadImage
import com.yaros.sweetshopviki.data.models.Categories
import com.yaros.sweetshopviki.databinding.CategoryCardBinding
class CategoriesAdapter (private var categoriesList: ArrayList<Categories>) :
RecyclerView.Adapter<CategoriesAdapter.CategoryCardDesign>() {
var onClick: (Categories) -> Unit = {}
class CategoryCardDesign(val categoryCardBinding: CategoryCardBinding) :
RecyclerView.ViewHolder(categoryCardBinding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryCardDesign {
val layoutInflater = LayoutInflater.from(parent.context)
val categoryCardBinding = CategoryCardBinding.inflate(layoutInflater, parent, false)
return CategoryCardDesign(categoryCardBinding)
}
override fun onBindViewHolder(holder: CategoryCardDesign, position: Int) {
val category = categoriesList[position]
holder.categoryCardBinding.apply {
categoryText.text = category.name
categoryImageView.loadImage(category.imagePath)
root.setOnClickListener {
onClick(category)
}
}
holder.categoryCardBinding.root.animation =
AnimationUtils.loadAnimation(holder.itemView.context, R.anim.recyclerview_anim)
}
override fun getItemCount(): Int {
return categoriesList.size
}
}
@@ -0,0 +1,107 @@
package com.yaros.sweetshopviki.ui.category
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.gone
import com.yaros.sweetshopviki.common.visible
import com.yaros.sweetshopviki.data.models.Categories
import com.yaros.sweetshopviki.data.repo.Repository
import com.yaros.sweetshopviki.databinding.FragmentCategoriesBinding
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
class CategoriesFragment : Fragment(R.layout.fragment_categories) {
private val binding by viewBinding(FragmentCategoriesBinding::bind)
private val viewModel by lazy { CategoriesViewModel(requireContext()) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val tryAgain: Button = requireView().findViewById<View>(R.id.tryAgain) as Button
(activity as AppCompatActivity?)!!.supportActionBar!!.title =
resources.getString(R.string.categories)
(activity as AppCompatActivity?)!!.supportActionBar!!.setDisplayHomeAsUpEnabled(false)
binding.apply {
viewModel.apply {
getCategories()
initObservers()
tryAgain.setOnClickListener {
getCategories()
}
}
}
}
private fun initObservers() {
binding.apply {
viewModel.apply {
val errorLayout: LinearLayout =
requireView().findViewById<View>(R.id.errorLayout) as LinearLayout
isLoading.observe(viewLifecycleOwner) {
when (it!!) {
Repository.LOADING.LOADING -> {
shimmerLayout.apply {
startShimmer()
visible()
}
categoriesRecyclerView.gone()
errorLayout.gone()
}
Repository.LOADING.DONE -> {
shimmerLayout.apply {
stopShimmer()
gone()
}
categoriesRecyclerView.visible()
errorLayout.gone()
}
Repository.LOADING.ERROR -> {
shimmerLayout.apply {
stopShimmer()
gone()
}
categoriesRecyclerView.gone()
errorLayout.visible()
}
}
}
categoryList.observe(viewLifecycleOwner) { categories ->
val productAdapter = CategoriesAdapter(categories as ArrayList<Categories>)
categoriesRecyclerView.adapter = productAdapter
productAdapter.onClick = ::clickCategory
}
categoriesRecyclerView.layoutManager = GridLayoutManager(context, 2)
categoriesRecyclerView.setHasFixedSize(true)
}
}
}
private fun clickCategory(category: Categories) {
val categoryNavigation =
CategoriesFragmentDirections.actionCategoriesFragmentToProductsFragment(
category
)
findNavController().navigate(categoryNavigation)
}
}
@@ -0,0 +1,26 @@
package com.yaros.sweetshopviki.ui.category
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yaros.sweetshopviki.data.models.Categories
import com.yaros.sweetshopviki.data.repo.Repository
import kotlinx.coroutines.launch
class CategoriesViewModel (context: Context) : ViewModel() {
private val repository = Repository(context)
var categoryList: LiveData<List<Categories>> = repository.categoriesList
var isLoading: LiveData<Repository.LOADING> = repository.isLoading
fun getCategories() {
viewModelScope.launch {
repository.getCategories()
}
}
}
@@ -0,0 +1,33 @@
package com.yaros.sweetshopviki.ui.login
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import com.yaros.sweetshopviki.databinding.ActivityLoginBinding
import com.yaros.sweetshopviki.ui.MainActivity
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.hide()
Firebase.auth.currentUser?.let {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
binding.viewPager.adapter = ViewPagerAdapter(supportFragmentManager, lifecycle)
binding.tabBar.setupWithViewPager2(binding.viewPager)
}
}
@@ -0,0 +1,24 @@
package com.yaros.sweetshopviki.ui.login
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.yaros.sweetshopviki.ui.login.signin.SignInFragment
import com.yaros.sweetshopviki.ui.login.signup.SignUpFragment
class ViewPagerAdapter (fragmentManager: FragmentManager, lifecycle: Lifecycle) :
FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int {
return 2
}
override fun createFragment(position: Int): Fragment {
when (position) {
0 -> return SignInFragment()
1 -> return SignUpFragment()
}
return SignInFragment()
}
}
@@ -0,0 +1,117 @@
package com.yaros.sweetshopviki.ui.login.signin
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.data.repo.UserRepository
import com.yaros.sweetshopviki.databinding.FragmentSignInBinding
import com.yaros.sweetshopviki.ui.MainActivity
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
import www.sanju.motiontoast.MotionToast
import www.sanju.motiontoast.MotionToastStyle
class SignInFragment : Fragment(R.layout.fragment_sign_in) {
private val binding by viewBinding(FragmentSignInBinding::bind)
private val viewModel by lazy { SignInViewModel() }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply {
viewModel.apply {
initObservers()
btnSignIn.setOnClickListener {
signIn(
emailEditText.text.toString(),
passwordEditText.text.toString()
)
}
}
}
}
private fun initObservers() {
binding.apply {
viewModel.apply {
isLoading.observe(viewLifecycleOwner) {
when (it!!) {
UserRepository.LOADING.LOADING -> {
btnSignIn.startAnimation()
}
UserRepository.LOADING.DONE -> {
btnSignIn.revertAnimation {
btnSignIn.setBackgroundResource(R.drawable.rounded_bg3)
}
}
UserRepository.LOADING.ERROR -> {
btnSignIn.revertAnimation {
btnSignIn.setBackgroundResource(R.drawable.rounded_bg3)
}
}
}
}
isSignIn.observe(viewLifecycleOwner) {
if (it) {
MotionToast.createColorToast(
requireActivity(),
getString(R.string.success),
getString(R.string.login_success),
MotionToastStyle.SUCCESS,
MotionToast.GRAVITY_TOP or MotionToast.GRAVITY_CENTER,
MotionToast.LONG_DURATION,
ResourcesCompat.getFont(requireContext(), R.font.circular)
)
val intent = Intent(context, MainActivity::class.java)
startActivity(intent)
requireActivity().finish()
} else {
MotionToast.createColorToast(
requireActivity(),
getString(R.string.error),
getString(R.string.wrong_email_password),
MotionToastStyle.ERROR,
MotionToast.GRAVITY_TOP or MotionToast.GRAVITY_CENTER,
MotionToast.LONG_DURATION,
ResourcesCompat.getFont(requireContext(), R.font.circular)
)
}
}
isValidMail.observe(viewLifecycleOwner) {
if (it.not()) {
emailEditText.error = getString(R.string.invalid_mail)
} else {
emailEditText.error = ""
}
}
isInfosValid.observe(viewLifecycleOwner) {
if (it.not())
MotionToast.createColorToast(
requireActivity(),
getString(R.string.error),
getString(R.string.complete_not_entered_info),
MotionToastStyle.ERROR,
MotionToast.GRAVITY_TOP or MotionToast.GRAVITY_CENTER,
MotionToast.LONG_DURATION,
ResourcesCompat.getFont(requireContext(), R.font.circular)
)
}
}
}
}
}
@@ -0,0 +1,39 @@
package com.yaros.sweetshopviki.ui.login.signin
import android.util.Patterns
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.yaros.sweetshopviki.data.repo.UserRepository
class SignInViewModel : ViewModel() {
private var usersRepo = UserRepository()
val isSignIn: LiveData<Boolean> = usersRepo.isSignIn
val isLoading: LiveData<UserRepository.LOADING> = usersRepo.isLoading
private var _isValidMail = MutableLiveData<Boolean>()
val isValidMail: LiveData<Boolean> = _isValidMail
private var _isInfosValid = MutableLiveData<Boolean>()
val isInfosValid: LiveData<Boolean> = _isInfosValid
fun signIn(eMail: String, password: String) {
if (eMail.isEmpty() || password.isEmpty()) {
_isInfosValid.value = false
} else {
_isInfosValid.value = true
if (Patterns.EMAIL_ADDRESS.matcher(eMail).matches().not()) {
_isValidMail.value = false
} else {
_isValidMail.value = true
usersRepo.signIn(eMail, password)
}
}
}
}
@@ -0,0 +1,152 @@
package com.yaros.sweetshopviki.ui.login.signup
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.data.repo.UserRepository
import com.yaros.sweetshopviki.databinding.FragmentSignUpBinding
import com.yaros.sweetshopviki.ui.MainActivity
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
import www.sanju.motiontoast.MotionToast
import www.sanju.motiontoast.MotionToastStyle
class SignUpFragment : Fragment(R.layout.fragment_sign_up) {
private val binding by viewBinding(FragmentSignUpBinding::bind)
private val viewModel by lazy { SignUpViewModel() }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply {
viewModel.apply {
signUpButton.setOnClickListener {
signUp(
emailEditText.text.toString(),
passwordEditText.text.toString(),
confirmPasswordEditText.text.toString(),
phoneNumberEditText.text.toString(),
userNameEditText.text.toString()
)
}
initObservers()
}
}
}
private fun initObservers() {
with(binding) {
with(viewModel) {
isLoading.observe(viewLifecycleOwner) {
when (it!!) {
UserRepository.LOADING.LOADING -> {
signUpButton.startAnimation()
}
UserRepository.LOADING.DONE -> {
signUpButton.revertAnimation {
signUpButton.setBackgroundResource(R.drawable.rounded_bg3)
}
}
UserRepository.LOADING.ERROR -> {
signUpButton.revertAnimation {
signUpButton.setBackgroundResource(R.drawable.rounded_bg3)
}
}
}
}
isPasswordSixChar.observe(viewLifecycleOwner) {
if (it.not()) {
passwordInputLayout.error = getString(R.string.six_char_error)
} else {
passwordInputLayout.error = ""
}
}
isInfoValid.observe(viewLifecycleOwner) {
if (it.not()) MotionToast.createColorToast(
requireActivity(),
getString(R.string.error),
getString(R.string.complete_not_entered_info),
MotionToastStyle.ERROR,
MotionToast.GRAVITY_TOP or MotionToast.GRAVITY_CENTER,
MotionToast.LONG_DURATION,
ResourcesCompat.getFont(requireContext(), R.font.circular)
)
}
isValidMail.observe(viewLifecycleOwner) {
if (it.not()) {
emailInputLayout.error = getString(R.string.invalid_mail)
} else {
emailInputLayout.error = ""
}
}
isPasswordMatch.observe(viewLifecycleOwner) {
if (it.not()) {
passwordInputLayout.error = getString(R.string.password_match_error)
confirmPasswordInputLayout.error = getString(R.string.password_match_error)
} else {
passwordInputLayout.error = ""
confirmPasswordInputLayout.error = ""
}
}
isSignUp.observe(viewLifecycleOwner) {
if (it) {
MotionToast.createColorToast(
requireActivity(),
getString(R.string.success),
getString(R.string.sign_up_success),
MotionToastStyle.SUCCESS,
MotionToast.GRAVITY_TOP or MotionToast.GRAVITY_CENTER,
MotionToast.LONG_DURATION,
ResourcesCompat.getFont(requireContext(), R.font.circular)
)
clearFields()
val intent = Intent(context, MainActivity::class.java)
startActivity(intent)
requireActivity().finish()
} else {
emailInputLayout.error = getString(R.string.registered_mail)
}
}
}
}
}
private fun clearFields() {
with(binding) {
emailEditText.setText("")
emailInputLayout.error = ""
passwordEditText.setText("")
passwordInputLayout.error = ""
confirmPasswordEditText.setText("")
confirmPasswordInputLayout.error = ""
phoneNumberEditText.setText("")
phoneNumberInputLayout.error = ""
userNameEditText.setText("")
userNameInputLayout.error = ""
}
}
}
@@ -0,0 +1,64 @@
package com.yaros.sweetshopviki.ui.login.signup
import android.util.Log
import android.util.Patterns
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.yaros.sweetshopviki.data.repo.UserRepository
class SignUpViewModel : ViewModel() {
private var usersRepo = UserRepository()
private var _isInfoValid = MutableLiveData<Boolean>()
val isInfoValid: LiveData<Boolean> = _isInfoValid
private var _isValidMail = MutableLiveData<Boolean>()
val isValidMail: LiveData<Boolean> = _isValidMail
private var _isPasswordMatch = MutableLiveData<Boolean>()
val isPasswordMatch: LiveData<Boolean> = _isPasswordMatch
private var _isPasswordSixChar = MutableLiveData<Boolean>()
val isPasswordSixChar: LiveData<Boolean> = _isPasswordSixChar
val isSignUp: LiveData<Boolean> = usersRepo.isSignUp
val isLoading: LiveData<UserRepository.LOADING> = usersRepo.isLoading
fun signUp(
eMail: String,
password: String,
confirmPassword: String,
phoneNumber: String,
userName: String
) {
if (eMail.isEmpty() || password.isEmpty() || confirmPassword.isEmpty() || phoneNumber.isEmpty() || userName.isEmpty()) {
_isInfoValid.value = false
Log.d("SIGN_UP", "SUCCESS")
} else {
_isInfoValid.value = true
if (Patterns.EMAIL_ADDRESS.matcher(eMail).matches().not()) {
_isValidMail.value = false
} else {
_isValidMail.value = true
if (password != confirmPassword) {
_isPasswordMatch.value = false
} else {
if (password.length >= 6) {
_isPasswordSixChar.value = true
_isPasswordMatch.value = true
usersRepo.signUp(eMail, password, phoneNumber, userName)
} else {
_isPasswordSixChar.value = false
}
}
}
}
}
}
@@ -0,0 +1,125 @@
package com.yaros.sweetshopviki.ui.payment
import android.app.Dialog
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.common.getPaymentImages
import com.yaros.sweetshopviki.common.getPaymentNames
import com.yaros.sweetshopviki.databinding.FragmentPaymentBinding
class PaymentFragment : BottomSheetDialogFragment() {
private var _binding: FragmentPaymentBinding? = null
private val binding get() = _binding!!
private val viewModel by lazy { PaymentViewModel(requireContext()) }
private val args: PaymentFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentPaymentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = BottomSheetDialog(requireContext(), theme)
dialog.setOnShowListener {
val bottomSheetDialog = it as BottomSheetDialog
val parentLayout =
bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
parentLayout?.let { layout ->
val behaviour = BottomSheetBehavior.from(layout)
setupFullHeight(layout)
behaviour.state = BottomSheetBehavior.STATE_EXPANDED
behaviour.skipCollapsed = true
}
}
return dialog
}
private fun setupFullHeight(bottomSheet: View) {
val layoutParams = bottomSheet.layoutParams
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
bottomSheet.layoutParams = layoutParams
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply {
closePaymentScreen.setOnClickListener { findNavController().popBackStack() }
orderNow.setOnClickListener {
if (orderAddress.text.isEmpty().not()) {
showOrderSuccessDialog()
viewModel.clearBasket()
} else {
orderAddress.error = getString(R.string.address_error)
}
}
cancel.setOnClickListener { findNavController().popBackStack() }
val customAdapter =
SpinnerAdapter(
requireContext(),
getPaymentImages(),
requireContext().getPaymentNames()
)
paymentTypes.adapter = customAdapter
orderAmountPrice.text = args.totalPrice.formatPrice()
discountAmount.text = (args.totalPrice * 0.20).formatPrice()
orderPaymentTotalPrice.text =
((args.totalPrice) - (args.totalPrice * 0.20)).formatPrice()
}
}
private fun showOrderSuccessDialog() {
val alertDialog = AlertDialog.Builder(requireContext())
val factory = LayoutInflater.from(requireContext())
val view = factory.inflate(R.layout.dialog_order_approved, null)
alertDialog.setView(view)
val dialog = alertDialog.create()
dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.show()
dialog.setCancelable(false)
val button = view.findViewById<View>(R.id.okay) as Button
button.setOnClickListener {
dialog.dismiss()
dialog.cancel()
findNavController().navigate(PaymentFragmentDirections.actionPaymentFragmentToCategoriesFragment())
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
@@ -0,0 +1,18 @@
package com.yaros.sweetshopviki.ui.payment
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yaros.sweetshopviki.data.repo.Repository
import kotlinx.coroutines.launch
class PaymentViewModel (context: Context) : ViewModel() {
private val repository = Repository(context)
fun clearBasket() {
viewModelScope.launch {
repository.clearBasket()
}
}
}
@@ -0,0 +1,41 @@
package com.yaros.sweetshopviki.ui.payment
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView
import android.widget.TextView
import com.yaros.sweetshopviki.R
class SpinnerAdapter(
var context: Context,
var imagesList: ArrayList<Int>,
var namesList: ArrayList<String>
) :
BaseAdapter() {
var inflter: LayoutInflater = LayoutInflater.from(context)
override fun getCount(): Int {
return imagesList.size
}
override fun getItem(i: Int): Any? {
return null
}
override fun getItemId(i: Int): Long {
return 0
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view: View? = inflter.inflate(R.layout.custom_spinner_items, null)
val icon = view?.findViewById<View>(R.id.imageView) as ImageView
val names = view.findViewById<View>(R.id.textView) as TextView
icon.setImageResource(imagesList[position])
names.text = namesList[position]
return view
}
}
@@ -0,0 +1,49 @@
package com.yaros.sweetshopviki.ui.product
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.recyclerview.widget.RecyclerView
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.common.loadImage
import com.yaros.sweetshopviki.data.models.Product
import com.yaros.sweetshopviki.databinding.ProductCardBinding
class ProductsAdapter (private var productList: ArrayList<Product>) :
RecyclerView.Adapter<ProductsAdapter.ProductsViewHolder>() {
class ProductsViewHolder(val productCardBinding: ProductCardBinding) :
RecyclerView.ViewHolder(productCardBinding.root)
var onClick: (Product) -> Unit = {}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ProductsViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val productCardBinding = ProductCardBinding.inflate(layoutInflater, parent, false)
return ProductsViewHolder(productCardBinding)
}
override fun onBindViewHolder(holder: ProductsViewHolder, position: Int) {
val product = productList[position]
holder.productCardBinding.apply {
productText.text = product.name
productPrice.text = product.price?.formatPrice()
productImageView.loadImage(product.imagePath.toString())
root.setOnClickListener { onClick(product) }
}
holder.productCardBinding.root.animation =
AnimationUtils.loadAnimation(holder.itemView.context, R.anim.recyclerview_anim)
}
override fun getItemCount(): Int {
return productList.size
}
}
@@ -0,0 +1,137 @@
package com.yaros.sweetshopviki.ui.product
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.gone
import com.yaros.sweetshopviki.common.visible
import com.yaros.sweetshopviki.data.models.Product
import com.yaros.sweetshopviki.data.repo.Repository
import com.yaros.sweetshopviki.databinding.FragmentProductsBinding
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
class ProductsFragment : Fragment(R.layout.fragment_products) {
private val binding by viewBinding(FragmentProductsBinding::bind)
private val viewModel by lazy { ProductsViewModel(requireContext()) }
private val args: ProductsFragmentArgs by navArgs()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val category = args.category
val tryAgain: Button = requireView().findViewById<View>(R.id.tryAgain) as Button
(activity as AppCompatActivity?)!!.supportActionBar!!.title = category.name
(activity as AppCompatActivity?)!!.supportActionBar!!.setDisplayHomeAsUpEnabled(true)
binding.apply {
viewModel.apply {
getProducts(category.id)
initObservers()
tryAgain.setOnClickListener {
getProducts(category.id)
}
}
}
initToolbarMenu()
}
private fun initToolbarMenu() {
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.search, menu)
val item = menu.findItem(R.id.action_search)
item.isVisible = false
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
android.R.id.home -> {
findNavController().popBackStack()
true
}
else -> false
}
}
}, viewLifecycleOwner, Lifecycle.State.RESUMED)
}
private fun initObservers() {
binding.apply {
viewModel.apply {
val errorLayout: LinearLayout =
requireView().findViewById<View>(R.id.errorLayout) as LinearLayout
isLoading.observe(viewLifecycleOwner) {
when (it!!) {
Repository.LOADING.LOADING -> {
shimmerLayout.apply {
startShimmer()
visible()
}
productsRecyclerView.gone()
errorLayout.gone()
}
Repository.LOADING.DONE -> {
shimmerLayout.apply {
stopShimmer()
gone()
}
productsRecyclerView.visible()
errorLayout.gone()
}
Repository.LOADING.ERROR -> {
shimmerLayout.apply {
stopShimmer()
gone()
}
productsRecyclerView.gone()
errorLayout.visible()
}
}
}
productList.observe(viewLifecycleOwner) { products ->
val productsAdapter = ProductsAdapter(products as ArrayList<Product>)
productsRecyclerView.adapter = productsAdapter
productsAdapter.onClick = ::clickProduct
}
productsRecyclerView.layoutManager = LinearLayoutManager(context)
productsRecyclerView.setHasFixedSize(true)
}
}
}
private fun clickProduct(product: Product) {
val productNavigation =
ProductsFragmentDirections.actionProductsFragmentToProductDetailFragment(product)
findNavController().navigate(productNavigation)
}
}
@@ -0,0 +1,26 @@
package com.yaros.sweetshopviki.ui.product
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yaros.sweetshopviki.data.models.Product
import com.yaros.sweetshopviki.data.repo.Repository
import kotlinx.coroutines.launch
class ProductsViewModel (context: Context) : ViewModel() {
private val repository = Repository(context)
var productList: LiveData<List<Product>> = repository.productList
var isLoading: LiveData<Repository.LOADING> = repository.isLoading
fun getProducts(categoryId: Int) {
viewModelScope.launch {
repository.getProducts(categoryId)
}
}
}
@@ -0,0 +1,102 @@
package com.yaros.sweetshopviki.ui.productdetail
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.common.loadImage
import com.yaros.sweetshopviki.common.showCustomToast
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.databinding.FragmentProductDetailBinding
class ProductDetailFragment : BottomSheetDialogFragment() {
private val viewModel by lazy { ProductDetailViewModel(requireContext()) }
private var _binding: FragmentProductDetailBinding? = null
private val binding get() = _binding!!
private val args: ProductDetailFragmentArgs by navArgs()
private var count: Int = 1
private var totalPrice: Double? = null
private var price: Double? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentProductDetailBinding.inflate(inflater, container, false)
return binding.root
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return BottomSheetDialog(requireContext(), R.style.AppBottomSheetDialogTheme)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val product = args.product
binding.apply {
productImage.loadImage(product.imagePath?.substring(39).toString())
totalPrice = product.price
price = product.price
productName.text = product.name
updatePrice()
productCount.text = count.toString()
increase.setOnClickListener { increaseCount() }
decrease.setOnClickListener { decreaseCount() }
cancel.setOnClickListener { findNavController().popBackStack() }
addToBasket.setOnClickListener {
viewModel.addBookToBasket(
ProductsBasketRoomModel(
productId = product.menuItemId!!,
productName = product.name,
productCount = count,
productPrice = totalPrice,
productImage = product.imagePath
)
)
Toast(requireContext()).showCustomToast(
getString(R.string.success_add_basket),
requireActivity()
)
findNavController().popBackStack()
}
}
}
private fun updatePrice() {
totalPrice = count * price!!
binding.productPrice.text = totalPrice!!.formatPrice()
}
private fun increaseCount() {
count += 1
binding.productCount.text = count.toString()
updatePrice()
}
private fun decreaseCount() {
if (count >= 2) {
count -= 1
binding.productCount.text = count.toString()
updatePrice()
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
@@ -0,0 +1,23 @@
package com.yaros.sweetshopviki.ui.productdetail
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yaros.sweetshopviki.data.models.ProductsBasketRoomModel
import com.yaros.sweetshopviki.data.repo.Repository
import kotlinx.coroutines.launch
class ProductDetailViewModel (context: Context) : ViewModel() {
private val repository = Repository(context)
fun addBookToBasket(productModel: ProductsBasketRoomModel) {
viewModelScope.launch {
repository.addBookToBasket(productModel)
}
}
}
@@ -0,0 +1,98 @@
package com.yaros.sweetshopviki.ui.profile
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.data.repo.UserRepository
import com.yaros.sweetshopviki.databinding.FragmentProfileBinding
import com.yaros.sweetshopviki.ui.login.LoginActivity
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
class ProfileFragment : Fragment(R.layout.fragment_profile) {
private val binding by viewBinding(FragmentProfileBinding::bind)
private val viewModel by lazy { ProfileViewModel() }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as AppCompatActivity?)!!.supportActionBar!!.title =
resources.getString(R.string.profile)
(activity as AppCompatActivity?)!!.supportActionBar!!.setDisplayHomeAsUpEnabled(false)
binding.apply {
viewModel.apply {
initObservers()
logOut.setOnClickListener {
signOut().also {
val intent = Intent(requireActivity(), LoginActivity::class.java)
startActivity(intent)
requireActivity().finish()
}
}
}
}
initToolbarMenu()
}
private fun initObservers() {
binding.apply {
viewModel.apply {
userInfo.observe(viewLifecycleOwner) {
username.text = it.userName
email.text = it.email
phone.text = it.phoneNumber
}
isLoading.observe(viewLifecycleOwner) {
when (it!!) {
UserRepository.LOADING.LOADING -> {
logOut.startAnimation()
}
UserRepository.LOADING.DONE -> {
logOut.revertAnimation {
logOut.setBackgroundResource(R.drawable.rounded_bg3)
}
}
UserRepository.LOADING.ERROR -> {
logOut.revertAnimation {
logOut.setBackgroundResource(R.drawable.rounded_bg3)
}
}
}
}
}
}
}
private fun initToolbarMenu() {
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.search, menu)
val item = menu.findItem(R.id.action_search)
item.isVisible = false
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return false
}
}, viewLifecycleOwner, Lifecycle.State.RESUMED)
}
}
@@ -0,0 +1,28 @@
package com.yaros.sweetshopviki.ui.profile
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import com.yaros.sweetshopviki.data.models.UserModel
import com.yaros.sweetshopviki.data.repo.UserRepository
class ProfileViewModel : ViewModel() {
private val usersRepo = UserRepository()
val userInfo: LiveData<UserModel>
get() = usersRepo.userInfo
val isLoading: LiveData<UserRepository.LOADING> = usersRepo.isLoading
init {
getUserInfo()
}
private fun getUserInfo() {
usersRepo.getUserInfo()
}
fun signOut() {
usersRepo.signOut()
}
}
@@ -0,0 +1,106 @@
package com.yaros.sweetshopviki.ui.search
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.Filter
import android.widget.Filterable
import androidx.recyclerview.widget.RecyclerView
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.formatPrice
import com.yaros.sweetshopviki.common.loadImage
import com.yaros.sweetshopviki.data.models.Product
import com.yaros.sweetshopviki.databinding.ProductCardBinding
class SearchAdapter :
RecyclerView.Adapter<SearchAdapter.ProductsViewHolder>(), Filterable {
var onClick: (Product) -> Unit = {}
private var productList = ArrayList<Product>()
var productFilterList = ArrayList<Product>()
init {
productFilterList = productList
}
class ProductsViewHolder(val productCardBinding: ProductCardBinding) :
RecyclerView.ViewHolder(productCardBinding.root)
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ProductsViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val productCardBinding = ProductCardBinding.inflate(layoutInflater, parent, false)
return ProductsViewHolder(productCardBinding)
}
override fun onBindViewHolder(holder: ProductsViewHolder, position: Int) {
val product = productFilterList[position]
holder.productCardBinding.apply {
productText.text = product.name
productPrice.text = product.price?.formatPrice()
productImageView.loadImage(product.imagePath.toString())
root.setOnClickListener { onClick(product) }
}
holder.productCardBinding.root.animation =
AnimationUtils.loadAnimation(holder.itemView.context, R.anim.recyclerview_anim)
}
fun updateList(list: List<Product>) {
productList.clear()
productList.addAll(list)
notifyDataSetChanged()
}
fun isListSame(): Boolean {
return productList == productFilterList
}
override fun getItemCount(): Int {
return productFilterList.size
}
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val searchText = constraint.toString().lowercase()
productFilterList = if (searchText.isEmpty()) {
productList
} else {
val resultList = ArrayList<Product>()
for (row in productList) {
row.name.let { productName ->
if (productName!!.lowercase().contains(searchText)) {
resultList.add(row)
}
}
}
resultList
}
val filterResults = FilterResults()
filterResults.values = productFilterList
return filterResults
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
productFilterList = results?.values as ArrayList<Product>
if (isListSame().not()) {
notifyDataSetChanged()
}
}
}
}
}
@@ -0,0 +1,148 @@
package com.yaros.sweetshopviki.ui.search
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.Button
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.yaros.sweetshopviki.R
import com.yaros.sweetshopviki.common.gone
import com.yaros.sweetshopviki.common.visible
import com.yaros.sweetshopviki.data.models.Product
import com.yaros.sweetshopviki.data.repo.Repository
import com.yaros.sweetshopviki.databinding.FragmentSearchBinding
import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding
class SearchFragment : Fragment(R.layout.fragment_search) {
private val binding by viewBinding(FragmentSearchBinding::bind)
private val viewModel by lazy { SearchViewModel(requireContext()) }
private val productsAdapter by lazy { SearchAdapter() }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as AppCompatActivity?)!!.supportActionBar!!.title =
resources.getString(R.string.search_product)
(activity as AppCompatActivity?)!!.supportActionBar!!.setDisplayHomeAsUpEnabled(false)
val tryAgain: Button = requireView().findViewById<View>(R.id.tryAgain) as Button
binding.apply {
viewModel.apply {
getSearch()
initObservers()
tryAgain.setOnClickListener {
getSearch()
}
}
}
initToolbarMenu()
}
private fun initToolbarMenu() {
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.search, menu)
val item = menu.findItem(R.id.action_search)
item.isVisible = true
val searchItem = menu.findItem(R.id.action_search)
val searchView = searchItem.actionView as SearchView
searchView.imeOptions = EditorInfo.IME_ACTION_DONE
searchView.queryHint = activity!!.getString(R.string.search) + "..."
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return true
}
override fun onQueryTextChange(newText: String): Boolean {
productsAdapter.filter.filter(newText)
return false
}
})
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return false
}
}, viewLifecycleOwner, Lifecycle.State.RESUMED)
}
private fun initObservers() {
binding.apply {
viewModel.apply {
val errorLayout: LinearLayout =
requireView().findViewById(R.id.errorLayout)
isLoading.observe(viewLifecycleOwner) {
when (it!!) {
Repository.LOADING.LOADING -> {
shimmerLayout.apply {
startShimmer()
visible()
}
productsRecyclerView.gone()
errorLayout.gone()
}
Repository.LOADING.DONE -> {
shimmerLayout.apply {
stopShimmer()
gone()
}
productsRecyclerView.visible()
errorLayout.gone()
}
Repository.LOADING.ERROR -> {
shimmerLayout.apply {
stopShimmer()
gone()
}
productsRecyclerView.gone()
errorLayout.visible()
}
}
}
productList.observe(viewLifecycleOwner) { products ->
productsRecyclerView.adapter = productsAdapter.also { adapter ->
adapter.updateList(products)
adapter.onClick = ::clickProduct
}
}
productsRecyclerView.layoutManager = LinearLayoutManager(context)
productsRecyclerView.setHasFixedSize(true)
}
}
}
private fun clickProduct(product: Product) {
val productNavigation =
SearchFragmentDirections.actionSearchFragmentToProductDetailFragment(product)
findNavController().navigate(productNavigation)
}
}
@@ -0,0 +1,23 @@
package com.yaros.sweetshopviki.ui.search
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yaros.sweetshopviki.data.models.Product
import com.yaros.sweetshopviki.data.repo.Repository
import kotlinx.coroutines.launch
class SearchViewModel (context: Context) : ViewModel() {
private val repository = Repository(context)
var productList: LiveData<List<Product>> = repository.searchList
var isLoading: LiveData<Repository.LOADING> = repository.isLoading
fun getSearch() {
viewModelScope.launch {
repository.getSearch()
}
}
}
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXScale="0.5"
android:fromYScale="0.5"
android:toXScale="1"
android:toYScale="1"
android:pivotY="50%"
android:pivotX="50%">
</scale>
<!--<translate-->
<!-- android:fromYDelta="100%"-->
<!-- android:fromXDelta="100%"-->
<!-- android:toYDelta="0%"-->
<!-- android:toXDelta="0%"-->
<!-- android:duration="500"-->
<!-- xmlns:android="http://schemas.android.com/apk/res/android" />-->
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/background" />
<corners
android:topLeftRadius="25dp"
android:topRightRadius="25dp" />
</shape>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#FFFFFF" />
<stroke
android:width="0.8dp"
android:color="@color/primary" />
<corners
android:radius="5dp"
/>
</shape>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/black"/>
<corners android:radius="20dp"/>
</shape>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="@color/white"/>
<corners
android:radius="20dp" />
</shape>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="50dp"
android:height="50dp"
android:viewportWidth="50"
android:viewportHeight="50">
<path
android:pathData="M6,5C3.793,5 2,6.793 2,9L2,12L44,12L44,9C44,6.793 42.207,5 40,5ZM2,17L2,31C2,33.207 3.793,35 6,35L40,35C42.207,35 44,33.207 44,31L44,17ZM9,20L25,20L25,22L9,22ZM46,24.0625L46,31C46,34.3086 43.3086,37 40,37L6,37C5.8789,37 5.7461,36.9766 5.625,36.9688L6.5938,42.3125C6.7813,43.3672 7.3438,44.2969 8.2188,44.9063C8.8984,45.3828 9.6875,45.625 10.5,45.625C10.7344,45.625 10.9844,45.6055 11.2188,45.5625L44.6875,39.5938C45.7383,39.4063 46.6719,38.8125 47.2813,37.9375C47.8906,37.0625 48.125,36.0195 47.9375,34.9688Z"
android:fillColor="@color/black"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8,9h8v10L8,19L8,9zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,4L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,8l-8,5 -8,-5L4,6l8,5 8,-5v2z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M18.06,22.99h1.66c0.84,0 1.53,-0.64 1.63,-1.46L23,5.05h-5L18,1h-1.97v4.05h-4.97l0.3,2.34c1.71,0.47 3.31,1.32 4.27,2.26 1.44,1.42 2.43,2.89 2.43,5.29v8.05zM1,21.99L1,21h15.03v0.99c0,0.55 -0.45,1 -1.01,1L2.01,22.99c-0.56,0 -1.01,-0.45 -1.01,-1zM16.03,14.99c0,-8 -15.03,-8 -15.03,0h15.03zM1.02,17h15v2h-15z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5,-5L11,7zM20,19h-8v2h8c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2h-8v2h8V19z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17,7l-1.41,1.41L18.17,11H8v2h10.17l-2.58,2.58L17,17l5,-5zM4,5h8V3H4c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h8v-2H4V5z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M13,8c0,-2.21 -1.79,-4 -4,-4S5,5.79 5,8s1.79,4 4,4S13,10.21 13,8zM15,10v2h3v3h2v-3h3v-2h-3V7h-2v3H15zM1,18v2h16v-2c0,-2.66 -5.33,-4 -8,-4S1,15.34 1,18z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1 -9.39,0 -17,-7.61 -17,-17 0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#fff"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17.21,9l-4.38,-6.56c-0.19,-0.28 -0.51,-0.42 -0.83,-0.42 -0.32,0 -0.64,0.14 -0.83,0.43L6.79,9L2,9c-0.55,0 -1,0.45 -1,1 0,0.09 0.01,0.18 0.04,0.27l2.54,9.27c0.23,0.84 1,1.46 1.92,1.46h13c0.92,0 1.69,-0.62 1.93,-1.46l2.54,-9.27L23,10c0,-0.55 -0.45,-1 -1,-1h-4.79zM9,9l3,-4.4L15,9L9,9zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
</vector>
+9
View File
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M22,2C18.686,2 16,4.686 16,8C16,11.314 18.686,14 22,14C25.314,14 28,11.314 28,8C28,4.686 25.314,2 22,2zM20.0566,5L23.9434,5L23.9434,6.1582L21.2031,6.1582L21.0938,7.5137L21.1719,7.5137C21.3989,7.1497 21.8112,6.9141 22.4102,6.9141C23.5192,6.9141 24.3125,7.737 24.3125,8.875C24.3115,10.138 23.3817,11 21.9727,11C20.6167,11 19.7085,10.2036 19.6875,9.1426L21.0352,9.1426C21.1042,9.5716 21.4934,9.8555 21.9824,9.8555C22.5244,9.8555 22.9102,9.4821 22.9102,8.9121C22.9102,8.3291 22.5205,7.9414 21.9785,7.9414C21.5655,7.9414 21.2758,8.1278 21.0898,8.4238L19.7813,8.4238L20.0566,5zM4,10A2,2 0,0 0,3.6152 10.0391C3.6019,10.0417 3.5894,10.046 3.5762,10.0488A2,2 0,0 0,3.2363 10.1543C3.2257,10.1587 3.2156,10.1634 3.2051,10.168A2,2 0,0 0,2.8887 10.3379C2.8867,10.3392 2.8847,10.3405 2.8828,10.3418A2,2 0,0 0,2.873 10.3496A2,2 0,0 0,2.5918 10.5801C2.5859,10.5859 2.582,10.5937 2.5762,10.5996A2,2 0,0 0,2.3438 10.8809C2.3419,10.8835 2.3397,10.886 2.3379,10.8887A2,2 0,0 0,2.1582 11.2207C2.158,11.2212 2.1584,11.2221 2.1582,11.2227A2,2 0,0 0,2.041 11.5977A2,2 0,0 0,2 12L2,24A2,2 0,0 0,2.0391 24.3848C2.0417,24.3981 2.046,24.4106 2.0488,24.4238A2,2 0,0 0,2.1543 24.7637C2.1587,24.7743 2.1634,24.7844 2.168,24.7949A2,2 0,0 0,2.3379 25.1113C2.3415,25.1167 2.3459,25.1216 2.3496,25.127A2,2 0,0 0,2.5801 25.4082C2.5859,25.4141 2.5937,25.418 2.5996,25.4238A2,2 0,0 0,2.8809 25.6563C2.8835,25.6581 2.886,25.6603 2.8887,25.6621A2,2 0,0 0,3.2207 25.8418C3.2212,25.842 3.2221,25.8416 3.2227,25.8418A2,2 0,0 0,3.5977 25.959A2,2 0,0 0,4 26L26,26A2,2 0,0 0,26.3848 25.9609C26.3981,25.9583 26.4106,25.954 26.4238,25.9512A2,2 0,0 0,26.7637 25.8457C26.7743,25.8413 26.7844,25.8366 26.7949,25.832A2,2 0,0 0,27.1113 25.6621A2,2 0,0 0,27.1172 25.6582C27.1206,25.6559 27.1235,25.6528 27.127,25.6504A2,2 0,0 0,27.4082 25.4199A2,2 0,0 0,27.4141 25.4141C27.418,25.4101 27.4199,25.4044 27.4238,25.4004A2,2 0,0 0,27.6563 25.1191A2,2 0,0 0,27.6582 25.1172C27.6595,25.1153 27.6608,25.1133 27.6621,25.1113A2,2 0,0 0,27.8418 24.7793A2,2 0,0 0,27.8418 24.7773A2,2 0,0 0,27.959 24.4023A2,2 0,0 0,28 24L28,13.2793C27.428,13.9293 26.754,14.4849 26,14.9219L25.998,22A2,2 0,0 0,24 24L6,24A2,2 0,0 0,4 22L4,14A2,2 0,0 0,6 12L15.0781,12C14.7191,11.381 14.4447,10.71 14.2617,10L4,10zM15,14C12.791,14 11,16.015 11,18.5C11,19.922 11.5977,21.175 12.5137,22L17.4863,22C18.4023,21.175 19,19.922 19,18.5C19,16.015 17.209,14 15,14zM7,17A1,1 0,0 0,6 18A1,1 0,0 0,7 19A1,1 0,0 0,8 18A1,1 0,0 0,7 17zM23,17A1,1 0,0 0,22 18A1,1 0,0 0,23 19A1,1 0,0 0,24 18A1,1 0,0 0,23 17z"
android:fillColor="#F9AA33"/>
</vector>
+9
View File
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M4,4C4,4 2,8 2,12C2,15.595 3.757,18.551 8,18.949L8,23.242L4.738,24.031L4.738,24.033A1,1 0,0 0,5 26L8.832,26A1,1 0,0 0,9.158 26L13,26A1,1 0,0 0,13.262 24.031L10,23.242L10,18.949C14.243,18.551 16,15.595 16,12C16,8 14,4 14,4L9,4L4,4zM19,4C18.448,4 18,4.448 18,5L18,10.785C18,13.127 19.541,15.232 21.734,15.822L21,23.826L21.008,23.826A2,2 0,0 0,21 24A2,2 0,0 0,23 26A2,2 0,0 0,25 24A2,2 0,0 0,24.99 23.826L24.992,23.826L24.26,15.834C26.41,15.275 28,13.325 28,11L28,5C28,4.448 27.552,4 27,4C26.448,4 26,4.448 26,5L26,10C26,10.553 25.552,11 25,11C24.448,11 24,10.553 24,10L24,5C24,4.448 23.552,4 23,4C22.448,4 22,4.448 22,5L22,10C22,10.553 21.552,11 21,11C20.448,11 20,10.553 20,10L20,5C20,4.448 19.552,4 19,4zM22.992,15.996C22.995,15.996 22.997,15.998 23,15.998L23,22A2,2 0,0 0,22.992 22L22.992,15.996z"
android:fillColor="#FAAB1A"/>
</vector>
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,13H5v-2h14v2z"/>
</vector>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#C2C2C2" />
<corners android:radius="50dp" />
</shape>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#C2C2C2" />
<corners android:radius="10dp" />
</shape>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/black" />
<corners android:radius="20dp" />
</shape>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#A3ADB3"/>
<corners android:radius="20dp"/>
</shape>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="oval"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white"></solid>
</shape>
+7
View File
@@ -0,0 +1,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
<corners android:radius="5dp" />
<stroke
android:width="0.8dp"
android:color="@color/primary" />
</shape>
Binary file not shown.
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.login.LoginActivity">
<nl.joery.animatedbottombar.AnimatedBottomBar
android:id="@+id/tabBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
app:abb_animationInterpolator="@android:anim/overshoot_interpolator"
app:abb_badgeBackgroundColor="@color/white"
app:abb_badgeTextColor="@color/white"
app:abb_iconSize="30dp"
app:abb_indicatorAppearance="round"
app:abb_indicatorColor="@color/black"
app:abb_indicatorHeight="5dp"
app:abb_indicatorLocation="bottom"
app:abb_indicatorMargin="16dp"
app:abb_selectedIndex="0"
app:abb_selectedTabType="icon"
app:abb_tabColor="@color/white"
app:abb_tabColorSelected="@color/white"
app:abb_tabs="@menu/tabs"
app:abb_textAppearance="@style/CustomText"
app:abb_textSize="16sp"
app:abb_textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabBar" />
</androidx.constraintlayout.widget.ConstraintLayout>
+39
View File
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/navigation_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
<me.ibrahimsn.lib.SmoothBottomBar
android:id="@+id/navigation_view"
android:layout_width="match_parent"
android:layout_height="60dp"
app:backgroundColor="@color/primary"
app:cornerRadius="0dp"
app:corners="all"
app:iconSize="22dp"
app:iconTint="@color/black"
app:iconTintActive="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/menu"
app:textColor="@color/black"
app:textSize="15sp" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.SplashActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
+104
View File
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView 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:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="@dimen/margin_small"
app:cardCornerRadius="50dp"
app:cardElevation="@dimen/card_elevation_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:id="@+id/materialCardView2"
android:layout_width="60dp"
android:layout_height="60dp"
app:cardCornerRadius="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<TextView
android:id="@+id/productCount"
android:layout_width="60dp"
android:layout_height="60dp"
android:gravity="center"
android:padding="5dp"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold"
android:translationZ="90dp"
tools:text="3X" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/productText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start|center"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:gravity="start"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold"
android:translationZ="90dp"
tools:text="textView" />
<TextView
android:id="@+id/productPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:gravity="center"
android:text="0.00 ₽"
android:textAllCaps="false"
android:textColor="@color/green"
android:textSize="15sp"
android:textStyle="bold"
android:translationZ="90dp" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/deleteBasketProduct"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="10dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/red100"
app:cardCornerRadius="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="35dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:contentDescription="@string/delete"
android:padding="@dimen/padding_small"
app:srcCompat="@drawable/ic_baseline_delete_outline_24"
app:tint="@color/red800" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
+51
View File
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView 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/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_small"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="20dp"
app:cardElevation="@dimen/card_elevation_small"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/categoryImageView"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/categoryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/margin_small"
android:gravity="start"
android:text="textView"
android:textAllCaps="true"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold"
android:translationZ="90dp" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp"
android:src="@drawable/ic_cash" />
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="5dp"
android:text="Demo"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/toast_layout_root"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="top|center_horizontal"
android:background="@drawable/custom_rounded_toast_bg"
android:gravity="top"
android:orientation="horizontal"
android:weightSum="1">
<ImageView
android:layout_width="40dp"
android:layout_height="match_parent"
android:src="@drawable/ic_baseline_check_circle_24"
app:tint="@color/primary" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:gravity="center"
android:textColor="@color/primary"
android:textSize="18sp"
android:textStyle="bold"
tools:text="Custom Toast" />
</LinearLayout>
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:orientation="vertical"
android:padding="2dp">
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/rounded_corners"
android:elevation="4dp"
android:gravity="center"
android:outlineProvider="none"
android:translationZ="90dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="2dp"
android:background="@drawable/dialog_bg"
android:orientation="vertical"
android:paddingTop="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/titlenot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/order_approved"
android:textColor="@color/black"
android:textSize="22dp"
android:textStyle="bold">
</TextView>
<View
android:layout_width="wrap_content"
android:layout_height="2dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="10dp"
android:background="@color/primary" />
<TextView
android:id="@+id/bodynot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:gravity="center"
android:text="@string/we_will_send_info"
android:textColor="@color/black"
android:textSize="17sp">
</TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal"
android:weightSum="1">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/okay"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@drawable/rounded_bg2"
android:gravity="center"
android:text="@string/okay"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/errorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="visible"
android:weightSum="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/tryAgain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="15dp"
android:background="@drawable/rounded_bg2"
android:text="@string/try_again"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold"
app:rippleColor="@color/white" />
</LinearLayout>
+149
View File
@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.basket.BasketFragment">
<LinearLayout
android:id="@+id/emptyLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
android:weightSum="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="@string/empty_basket"
android:textAlignment="center"
android:textAllCaps="true"
android:textColor="@color/primary"
android:textSize="20sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/addOrder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="15dp"
android:background="@drawable/rounded_bg2"
android:text="@string/go_shopping"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold"
app:rippleColor="@color/white" />
</LinearLayout>
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/shimmerLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp">
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/basketRecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/approveLayout"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/approveLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
android:visibility="gone"
app:cardBackgroundColor="#E4E4E4"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:gravity="bottom"
android:orientation="horizontal"
android:weightSum="2">
<TextView
android:id="@+id/totalAmount"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold"
tools:text="150,00 ₺" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/approveBasket"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="@drawable/rounded_bg2"
android:text="@string/approve_basket"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.category.CategoriesFragment">
<include
layout="@layout/error_page"
tools:visibility="gone" />
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/shimmerLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp">
<include layout="@layout/placeholder" />
<include layout="@layout/placeholder" />
<include layout="@layout/placeholder" />
<include layout="@layout/placeholder" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/categoriesRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,513 @@
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.payment.PaymentFragment">
<FrameLayout
android:id="@+id/bottomSheetNavHost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/primary"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center|start"
android:paddingStart="10dp"
android:text="@string/payment_screen"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/closePaymentScreen"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginHorizontal="10dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
android:visibility="gone"
app:cardBackgroundColor="#FFFFFF"
app:cardCornerRadius="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="35dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:contentDescription="@string/close"
android:padding="@dimen/padding_small"
app:srcCompat="@drawable/ic_baseline_close_24"
app:tint="@color/primary" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/cardView"
app:layout_constraintTop_toBottomOf="@+id/linearLayout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/materialCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="8dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="@string/type_order_note"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="3dp"
android:background="@color/primary" />
<EditText
android:id="@+id/orderNote"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="left"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:layout_weight="1"
android:background="@drawable/custom_edittext"
android:gravity="left"
android:hint="@string/order_note_hint"
android:padding="5dp" />
<androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/dont_knock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:text="@string/dont_knock"
android:textSize="16sp" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/materialCardView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="8dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="@string/address"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="3dp"
android:background="@color/primary" />
<EditText
android:id="@+id/orderAddress"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_gravity="left"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:layout_weight="1"
android:background="@drawable/custom_edittext"
android:gravity="left"
android:hint="@string/order_address"
android:padding="5dp" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="8dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="@string/payment_type"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="3dp"
android:background="@color/primary" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:layout_weight=".28"
android:background="@drawable/spinner"
android:orientation="horizontal"
android:paddingRight="5dp">
<Spinner
android:id="@+id/paymentTypes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:background="@android:color/transparent"
android:gravity="center"
android:spinnerMode="dropdown" />
<ImageView
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:paddingBottom="5dp"
android:src="@drawable/drop"
app:tint="@color/primary" />
</RelativeLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="8dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="@string/payment_summary"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="3dp"
android:background="@color/primary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:background="@drawable/spinner"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:weightSum="2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:text="@string/order_amount"
android:textColor="@color/primary"
android:textSize="16sp" />
<TextView
android:id="@+id/order_amount_price"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:textColor="#4CAF50"
android:textSize="16sp" />
</LinearLayout>
<View
android:id="@+id/pointDiscountLine"
android:layout_width="match_parent"
android:layout_height="0.8dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="3dp"
android:background="@color/primary"
android:visibility="visible" />
<View
android:id="@+id/discountLine"
android:layout_width="match_parent"
android:layout_height="0.8dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="3dp"
android:background="@color/primary"
android:visibility="gone" />
<LinearLayout
android:id="@+id/discountLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:visibility="visible"
android:weightSum="2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:text="@string/discount_amount"
android:textColor="@color/primary"
android:textSize="16sp" />
<TextView
android:id="@+id/discount_amount"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:textColor="@color/red900"
android:textSize="16sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.8dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="3dp"
android:background="@color/primary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:weightSum="2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:text="@string/payment_total_amount"
android:textColor="@color/primary"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/order_payment_total_price"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:textColor="#4CAF50"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:gravity="bottom"
android:orientation="horizontal"
android:weightSum="2">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="7dp"
android:layout_weight="1"
android:background="@drawable/rounded_bg3"
android:text="@string/cancel"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/orderNow"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="7dp"
android:layout_weight="1"
android:background="@drawable/rounded_bg2"
android:text="@string/orderNow"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,233 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|top"
android:orientation="vertical"
tools:context=".ui.productdetail.ProductDetailFragment">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/productImage"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:transitionName="productImage"
tools:srcCompat="@tools:sample/avatars" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp"
android:transitionName="productInfoLayout">
<TextView
android:id="@+id/productName"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_weight="1"
android:textAlignment="center"
android:textColor="@color/primary"
android:textSize="18sp"
android:textStyle="bold"
android:transitionName="productName"
tools:text="Ürün Adı" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5dp"
android:weightSum="2">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:id="@+id/decrease"
android:layout_width="40dp"
android:layout_height="40dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/red100"
app:cardCornerRadius="50dp"
app:strokeColor="@color/red800"
app:strokeWidth="2dp">
<ImageView
android:layout_width="35dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:contentDescription="@string/delete"
android:padding="2dp"
app:srcCompat="@drawable/ic_remove_black_24dp"
app:tint="@color/red800" />
</com.google.android.material.card.MaterialCardView>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/productCount"
android:layout_width="60dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:autoSizeMaxTextSize="25sp"
android:autoSizeTextType="uniform"
android:gravity="center"
android:maxLines="1"
android:padding="5dp"
android:text="1"
android:textAlignment="center"
android:textColor="@color/primary"
android:textSize="25sp"
android:textStyle="bold" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/increase"
android:layout_width="40dp"
android:layout_height="40dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/green100"
app:cardCornerRadius="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:strokeColor="@color/green800"
app:strokeWidth="2dp">
<ImageView
android:layout_width="35dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:contentDescription="@string/delete"
android:padding="2dp"
app:srcCompat="@drawable/ic_add_black_24dp"
app:tint="@color/green800" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/productPrice"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:layout_weight="2"
android:autoSizeMaxTextSize="25sp"
android:autoSizeTextType="uniform"
android:gravity="right|center_vertical"
android:maxLines="1"
android:paddingLeft="5dp"
android:paddingEnd="10dp"
android:textColor="@color/primary"
android:textSize="25sp"
android:textStyle="bold"
android:transitionName="productPrice"
app:autoSizeStepGranularity="2sp"
tools:text="50,00 ₺" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:orientation="vertical"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:strokeColor="@color/primary"
app:strokeWidth="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:gravity="bottom"
android:orientation="horizontal"
android:weightSum="2">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="7dp"
android:layout_weight="1"
android:background="@drawable/rounded_bg3"
android:text="@string/cancel"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/addToBasket"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="7dp"
android:layout_weight="1"
android:background="@drawable/rounded_bg2"
android:text="@string/add_basket"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.product.ProductsFragment">
<include tools:visibility="gone" layout="@layout/error_page" />
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/shimmerLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp">
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/productsRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.profile.ProfileFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="106dp"
tools:layout_editor_absoluteY="0dp">
<ImageView
android:id="@+id/profileImage"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="133dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="128dp"
app:srcCompat="@drawable/ic_launcher_background"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/profileImage"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="@string/username_hint"
android:textColor="@color/black"
android:textSize="24sp" />
<Button
android:id="@+id/editProfileButton"
style="@android:style/Widget.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/username"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:background="@drawable/rounded_bg3"
android:text="@string/editusername"
android:textColor="@color/primary"
android:theme="@style/Button.White" />
<TextView
android:id="@+id/email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/editProfileButton"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="@string/e_mail_hint"
android:textColor="@color/black"
android:textSize="16sp" />
<TextView
android:id="@+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/email"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:text="@string/phone_number_hint"
android:textColor="@color/black"
android:textSize="16sp" />
<com.apachat.loadingbutton.core.customViews.CircularProgressButton
android:id="@+id/log_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/phone"
android:layout_centerHorizontal="true"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="50dp"
android:layout_weight="1"
android:background="@drawable/rounded_bg3"
android:text="@string/log_out"
android:textAllCaps="false"
android:textColor="@color/primary"
android:textSize="15sp"
android:textStyle="bold" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".ui.search.SearchFragment">
<include tools:visibility="gone" layout="@layout/error_page" />
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/shimmerLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp">
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
<include layout="@layout/product_placeholder" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/productsRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>

Some files were not shown because too many files have changed in this diff Show More