diff --git a/app/build.gradle b/app/build.gradle index debcfaf..ef309f0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 608e135..9708b21 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -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"> , + private val itemListener: ItemListener, +) : RecyclerView.Adapter() { + + + 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 + + +} + diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/CartViewHolder.kt b/app/src/main/java/otus/gpb/homework/viewandresources/CartViewHolder.kt new file mode 100644 index 0000000..4c30f72 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/viewandresources/CartViewHolder.kt @@ -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) + } + + + } + +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/ContactsActivity.kt b/app/src/main/java/otus/gpb/homework/viewandresources/ContactsActivity.kt index 25f1ffb..aa1e28b 100644 --- a/app/src/main/java/otus/gpb/homework/viewandresources/ContactsActivity.kt +++ b/app/src/main/java/otus/gpb/homework/viewandresources/ContactsActivity.kt @@ -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 = + ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, phoneTypes) + + + with(binding) { + textFieldPhoneType + .editText + ?.asClass() + ?.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 { + // + } + } + + + } + + } -} \ No newline at end of file +} + +fun Any.asClass(): T? = if (this as? T == null) null else this \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/ItemListener.kt b/app/src/main/java/otus/gpb/homework/viewandresources/ItemListener.kt new file mode 100644 index 0000000..93f0109 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/viewandresources/ItemListener.kt @@ -0,0 +1,8 @@ +package otus.gpb.homework.viewandresources + +import java.util.UUID + +interface ItemListener { + fun onItemClick(id: UUID) + +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/MainActivity.kt b/app/src/main/java/otus/gpb/homework/viewandresources/MainActivity.kt index 22b779c..c4b96c9 100644 --- a/app/src/main/java/otus/gpb/homework/viewandresources/MainActivity.kt +++ b/app/src/main/java/otus/gpb/homework/viewandresources/MainActivity.kt @@ -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) @@ -19,9 +24,31 @@ class MainActivity : AppCompatActivity() { } findViewById