Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ android {
kotlinOptions {
jvmTarget = '17'
}
buildFeatures {
viewBinding = true
}
}

dependencies {
implementation 'androidx.core:core-ktx:1.15.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.google.android.material:material:1.12.0'
implementation 'com.google.android.material:material:1.14.0-alpha05'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
}
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ViewResources"
android:theme="@style/Base.Theme"
tools:targetApi="31">
<activity
android:name=".CartActivity"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
package otus.gpb.homework.viewandresources

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import otus.gpb.homework.viewandresources.databinding.ActivityCartBinding
import otus.gpb.homework.viewandresources.dto.Product
import java.util.UUID

class CartActivity : AppCompatActivity(), ItemListener {

private val products by lazy { generateTestData() }
private val adapter by lazy { CartAdapter(products, this) }

lateinit var activityCartBinding: ActivityCartBinding

class CartActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_cart)
activityCartBinding = ActivityCartBinding.inflate(layoutInflater)
setContentView(activityCartBinding.root)
val cartListView = activityCartBinding.cartListView
cartListView.addItemDecoration(DividerItemDecoration(this, LinearLayout.VERTICAL))
cartListView.adapter = adapter
// adapter.notifyDataSetChanged()
activityCartBinding.orderTotalValue.text =
products.sumOf { it.price.replace("$", "").toInt() }.toString()
}

fun generateTestData() = Array(22) {
Product(
UUID.randomUUID(),
R.drawable.cart_item_icon,
"Product $it",
"Category $it",
"lorem ipsum dolor sit amet, consectetur adipiscing elit",
"$$it"
)
}.toMutableList()

override fun onItemClick(id: UUID) {
Toast.makeText(this, "Clicked on item with id $id", Toast.LENGTH_SHORT).show()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package otus.gpb.homework.viewandresources

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import otus.gpb.homework.viewandresources.databinding.CartItemBinding
import otus.gpb.homework.viewandresources.dto.Product

/**
* Cвязывает данные [Product] с представлениями [CartViewHolder]
* */
class CartAdapter(
private val dataSet: MutableList<Product>,
private val itemListener: ItemListener,
) : RecyclerView.Adapter<CartViewHolder>() {


fun removeItem(index: Int) {
dataSet.removeAt(index)
notifyItemRemoved(index)
}

/**
* [RecyclerView] вызывает этот метод всякий раз,
* когда ему необходимо создать новый ViewHolder .
* Метод создаёт и инициализирует ViewHolder и связанный с ним View ,
* но не заполняет содержимое представления,
* так как ViewHolder ещё не привязан к определённым данным.
* */
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartViewHolder {
val cartItemBinding: CartItemBinding =
CartItemBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return CartViewHolder(cartItemBinding, itemListener)
}

/**
* [RecyclerView] вызывает этот метод, чтобы связать ViewHolder с данными.
* Метод извлекает соответствующие данные и использует их для заполнения макета держателя представления.
* Например, если RecyclerView отображает список имён,
* метод может найти нужное имя в списке и заполнить виджет TextView держателя представления.
* */
override fun onBindViewHolder(holder: CartViewHolder, position: Int) =
holder.bind(dataSet[position])

override fun getItemCount() = dataSet.size


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package otus.gpb.homework.viewandresources

import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.imageview.ShapeableImageView
import otus.gpb.homework.viewandresources.databinding.CartItemBinding
import otus.gpb.homework.viewandresources.dto.Product

/**
* Обёртка вокруг View, и этим представлением управляет RecyclerView .
* */
class CartViewHolder(
private val cartItemBinding: CartItemBinding,
private val itemListener: ItemListener
) : RecyclerView.ViewHolder(cartItemBinding.root) {

init {
println("init CartViewHolder")
}

val productImageView: ImageView = cartItemBinding.productImage
val productNameView: TextView = cartItemBinding.productName
val categoryView: TextView = cartItemBinding.category
val descriptionView: TextView = cartItemBinding.description
val priceView: TextView = cartItemBinding.price


fun bind(product: Product) {
with(product) {
println("bind CartViewHolder with id $id.}")
//todo разобраться, почему без этой строки не отображается
productImageView.setImageResource(imageResId)
productNameView.text = productName
categoryView.text = category
descriptionView.text = description
priceView.text = price
}
cartItemBinding.root.setOnClickListener { it ->
itemListener.onItemClick(product.id)
}


}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,85 @@
package otus.gpb.homework.viewandresources

import androidx.appcompat.app.AppCompatActivity

import android.os.Bundle
import android.widget.ArrayAdapter
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.color.DynamicColors
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.textfield.MaterialAutoCompleteTextView
import otus.gpb.homework.viewandresources.databinding.ActivityContactsBinding
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone


class ContactsActivity : AppCompatActivity() {

private lateinit var binding: ActivityContactsBinding
private val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
private val dataPickerTitle by lazy { getString(R.string.data_picker_title) }
private val phoneTypes by lazy { resources.getStringArray(R.array.phone_type) }

override fun onCreate(savedInstanceState: Bundle?) {
DynamicColors.applyToActivityIfAvailable(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_contacts)
binding = ActivityContactsBinding.inflate(layoutInflater)
setContentView(binding.root)

val adapter: ArrayAdapter<String?> =
ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, phoneTypes)


with(binding) {
textFieldPhoneType
.editText
?.asClass<MaterialAutoCompleteTextView>()
?.setAdapter(adapter)

val datePickerBuilder = MaterialDatePicker
.Builder
.datePicker()
.setTitleText(dataPickerTitle)


if (editData.text.toString().isNotEmpty()) {
try {
dateFormat
.parse(editData.text.toString())
?.let {
datePickerBuilder.setSelection(it.time)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
val datePicker = datePickerBuilder.build()
editData.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
datePicker.addOnPositiveButtonClickListener { selection: Long ->
editData.setText(dateFormat.format(Date(selection)))
}
datePicker.addOnNegativeButtonClickListener {
editData.clearFocus()
}
datePicker.addOnDismissListener {
editData.clearFocus()
}
datePicker.show(supportFragmentManager, "birthday_date")

} else {
//
}
}


}


}
}
}

fun <T> Any.asClass(): T? = if (this as? T == null) null else this
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package otus.gpb.homework.viewandresources

import java.util.UUID

interface ItemListener {
fun onItemClick(id: UUID)

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package otus.gpb.homework.viewandresources

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class MainActivity : AppCompatActivity() {

private val dialog by lazy { createMaterialDialog() }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Expand All @@ -19,9 +24,31 @@ class MainActivity : AppCompatActivity() {
}

findViewById<Button>(R.id.signin_button).setOnClickListener {
MaterialAlertDialogBuilder(this)
.setView(R.layout.dialog_signin)
.show()
dialog.show()
}
}

/**
* Создаёт и настраивает MaterialAlertDialog для входа пользователя.
*
* Диалог включает в себя поля для ввода логина и пароля, а также кнопки подтверждения и отмены.
* При нажатии на кнопки логирует действия пользователя и закрывает диалог.
*
* @return Настроенный экземпляр [AlertDialog].
*/
private fun createMaterialDialog(): AlertDialog = MaterialAlertDialogBuilder(this)
.setTitle(R.string.dialog_title)
.setView(R.layout.dialog_signin)
.setPositiveButton(R.string.dialog_login_button) { dialog, which ->
Log.d("debug_granted", "chooseImageDialog onPositiveButtonClickListener.")
dialog.dismiss()
}
.setNegativeButton(R.string.dialog_canceled_button) { dialog, which ->
Log.d("debug_granted", "chooseImageDialog onNegativeButtonClickListener.")
dialog.dismiss()
}
.setOnDismissListener {
Log.d("debug_granted", "chooseImageDialog onDismissListener.")
}
.create()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package otus.gpb.homework.viewandresources.dto

import java.util.UUID

data class Product(
val id: UUID,
val imageResId: Int,
val productName: String,
val category: String,
val description: String,
val price: String
)
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/arrow_left.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- drawable/arrow_left.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z" />
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/bookmark.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="18dp"
android:viewportWidth="14"
android:viewportHeight="18">
<path
android:pathData="M0,18V2C0,1.45 0.196,0.979 0.587,0.587C0.979,0.196 1.45,0 2,0H12C12.55,0 13.021,0.196 13.413,0.587C13.804,0.979 14,1.45 14,2V18L7,15L0,18ZM2,14.95L7,12.8L12,14.95V2H2V14.95Z"
android:fillColor="#4E4343"/>
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/calendar.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="20dp"
android:viewportWidth="18"
android:viewportHeight="20">
<path
android:pathData="M6,14.5C5.3,14.5 4.708,14.258 4.225,13.775C3.742,13.292 3.5,12.7 3.5,12C3.5,11.3 3.742,10.708 4.225,10.225C4.708,9.742 5.3,9.5 6,9.5C6.7,9.5 7.292,9.742 7.775,10.225C8.258,10.708 8.5,11.3 8.5,12C8.5,12.7 8.258,13.292 7.775,13.775C7.292,14.258 6.7,14.5 6,14.5ZM2,20C1.45,20 0.979,19.804 0.587,19.413C0.196,19.021 0,18.55 0,18V4C0,3.45 0.196,2.979 0.587,2.588C0.979,2.196 1.45,2 2,2H3V0H5V2H13V0H15V2H16C16.55,2 17.021,2.196 17.413,2.588C17.804,2.979 18,3.45 18,4V18C18,18.55 17.804,19.021 17.413,19.413C17.021,19.804 16.55,20 16,20H2ZM2,18H16V8H2V18Z"
android:fillColor="#4E4343"/>
</vector>
Loading