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
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
viewBinding {
enabled = true
}
}

dependencies {
Expand Down
109 changes: 108 additions & 1 deletion app/src/main/java/otus/gpb/homework/viewandresources/CartActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,117 @@ package otus.gpb.homework.viewandresources

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView

class CartActivity : AppCompatActivity(), CartItemListener {
private lateinit var list :MutableList<CartItem>
private lateinit var adapter :CartItemAdapter
private val list_generate_size = 40
private var num = 1

private lateinit var recyclerView :RecyclerView
private lateinit var textCartItemCount :TextView
private lateinit var textCartOrderTotalAmount :TextView
private lateinit var textCartSubtotalAmount :TextView
private lateinit var textCartShippingAmount :TextView
private lateinit var textCartTaxAmount :TextView
private lateinit var textCartOrderTotal :TextView
private lateinit var textCartSubtotal :TextView
private lateinit var textCartShipping :TextView
private lateinit var textCartTax :TextView

class CartActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_cart)

recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
textCartOrderTotal = findViewById<TextView>(R.id.textCartOrderTotal)
textCartSubtotal = findViewById<TextView>(R.id.textCartSubtotal)
textCartShipping = findViewById<TextView>(R.id.textCartShipping)
textCartTax = findViewById<TextView>(R.id.textCartTax)
textCartItemCount = findViewById<TextView>(R.id.textCartItemCount)
textCartOrderTotalAmount = findViewById<TextView>(R.id.textCartOrderTotalAmount)
textCartSubtotalAmount = findViewById<TextView>(R.id.textCartSubtotalAmount)
textCartShippingAmount = findViewById<TextView>(R.id.textCartShippingAmount)
textCartTaxAmount = findViewById<TextView>(R.id.textCartTaxAmount)

adapter = CartItemAdapter(this)
list = generateList()

recyclerView.addItemDecoration(
DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
)
ItemTouchHelper(CartItemItemTouchCallbacks(this)).attachToRecyclerView(recyclerView)
recyclerView.adapter = adapter
adapter.setItems(this.list)

textCartOrderTotal.text = getString(R.string.order_total)
textCartSubtotal.text = getString(R.string.subtotal)
textCartShipping.text = getString(R.string.shipping)
textCartTax.text = getString(R.string.tax)
}

// Клик на товаре в корзине.
override fun onItemClick(item: CartItem) {
Toast.makeText(this, item.caption + "\n" + item.description, Toast.LENGTH_SHORT).show()
}

// Удаляет товар из корзины
override fun onItemSwiped(item: CartItem) {
val index = list.indexOf(item)
list.removeAt(index)
recyclerView.post { adapter.notifyItemRemoved(index) }
}

// Подгружает 40 новых товаров в корзину
override fun onLoadMoreItem() {
val position = list.size - 1
val newList = generateList()
list+= newList
recyclerView.post { adapter.notifyItemRangeInserted(position, newList.size) }
}

private fun generateList(): MutableList<CartItem> {
var totalAmount = 0
data class Item(val resId: Int, val name: String)
val items = listOf(
Item(R.drawable.im_goods, getString(R.string.subtotal)),
Item(R.drawable.im_sport, getString(R.string.sport)),
Item(R.drawable.im_groceries, getString(R.string.groceries)),
Item(R.drawable.im_food, getString(R.string.food))
)

val list = mutableListOf<CartItem>()
repeat(list_generate_size) {
val amount = (1..1000000).random()
totalAmount += amount
val i = (0..3).random()
val item = CartItem(
items[i].name,
getString(R.string.category) +" ${num++}",
formatAmount(amount),
getString(R.string.discription),
ResourcesCompat.getDrawable(getResources(), items[i].resId,null))
list.add(item)
}

textCartItemCount.text = "${num-1}" + getString(R.string.items_in_cart)
textCartOrderTotalAmount.text = formatAmount(totalAmount)
textCartSubtotalAmount.text = formatAmount((totalAmount.toFloat() * 0.85).toInt())
textCartShippingAmount.text = formatAmount((totalAmount.toFloat() * 0.20).toInt())
textCartTaxAmount.text = formatAmount((totalAmount.toFloat() * 0.1).toInt())

return list
}

private fun formatAmount(amount :Int) :String {
val first = amount / 100
val second = amount % 100
return String.format("$%d.%02d", first, second)
}
}
11 changes: 11 additions & 0 deletions app/src/main/java/otus/gpb/homework/viewandresources/CartItem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package otus.gpb.homework.viewandresources

import android.graphics.drawable.Drawable

data class CartItem (
val caption: String,
val category: String,
val price: String,
val description: String,
val image: Drawable? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package otus.gpb.homework.viewandresources

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

class CartItemAdapter(private val listener: CartItemListener) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private lateinit var list: MutableList<CartItem>

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.cart_item, parent, false)
return CartItemViewHolder(view, listener)
}

override fun getItemCount(): Int = list.size

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = list[position]
(holder as CartItemViewHolder).bind(item)

if(position == list.size - 1) {
listener.onLoadMoreItem()
}
}

fun setItems(items: MutableList<CartItem>) {
list = items
notifyItemInserted(0)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package otus.gpb.homework.viewandresources

interface CartItemListener {
fun onItemClick(item: CartItem)
fun onItemSwiped(item: CartItem)
fun onLoadMoreItem()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package otus.gpb.homework.viewandresources

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView

class CartItemItemTouchCallbacks(context : Context) : ItemTouchHelper.Callback(){

private val ic_trash = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_trash,null)
private val paint = Paint().apply { setARGB(0xFF, 0xA0,0xA0,0xFF) }
private val rect = Rect()
private lateinit var bitmap :Bitmap
private var ic_trash_size :Int = 0
private var once = false

override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
return makeMovementFlags(0, ItemTouchHelper.LEFT)
}

override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)

// При Swipe влево освободившееся место заполнить голубым фоном с иконкой архивирования
if( isCurrentlyActive && actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {

rect.set(viewHolder.itemView.width + dX.toInt(),
viewHolder.itemView.y.toInt(),
viewHolder.itemView.width + viewHolder.itemView.paddingRight,
viewHolder.itemView.y.toInt() + viewHolder.itemView.height)

c.drawRect(rect, paint)

if( ic_trash!= null ) {
if( !once ){
once = true
ic_trash_size = viewHolder.itemView.height / 2
bitmap = ic_trash.toBitmap(ic_trash_size, ic_trash_size)
}

c.drawBitmap(
bitmap,
(viewHolder.itemView.width - ic_trash_size - ic_trash_size / 2).toFloat(),
viewHolder.itemView.y + ic_trash_size / 2,
null
)
}
}
}

override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
TODO("Not yet implemented")
}

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
(viewHolder as CartItemViewHolder).listener.onItemSwiped(viewHolder.item)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package otus.gpb.homework.viewandresources

import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class CartItemViewHolder(
private val view: View,
val listener: CartItemListener
) : RecyclerView.ViewHolder(view) {

private var root = view.findViewById<ViewGroup>(R.id.cart_item_container)
private var image = view.findViewById<ImageView>(R.id.cart_item_image)
private var price = view.findViewById<TextView>(R.id.cart_item_price)
private var caption = view.findViewById<TextView>(R.id.cart_item_caption)
private var category = view.findViewById<TextView>(R.id.cart_item_category)
private var description = view.findViewById<TextView>(R.id.cart_item_description)

lateinit var item :CartItem

fun bind(item: CartItem){
root.setOnClickListener { listener.onItemClick(item) }
item.image?.let{ image.setImageDrawable(it) }
price.text = item.price
caption.text = item.caption
category.text = item.category
description.text = item.description
this.item = item
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class MainActivity : AppCompatActivity() {
Expand All @@ -21,6 +22,7 @@ class MainActivity : AppCompatActivity() {
findViewById<Button>(R.id.signin_button).setOnClickListener {
MaterialAlertDialogBuilder(this)
.setView(R.layout.dialog_signin)
.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.shape_round_corners,null))
.show()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package otus.gpb.homework.viewandresources.components

import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.withStyledAttributes
import otus.gpb.homework.viewandresources.R
import otus.gpb.homework.viewandresources.databinding.CompoundViewContactsBinding


class CompoundViewContacts @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStileAttr: Int = 0
) : ConstraintLayout(context, attrs, defStileAttr) {

private val binding: CompoundViewContactsBinding

init {
binding = CompoundViewContactsBinding.inflate(LayoutInflater.from(context), this)
initCustomAttibutes(attrs, defStileAttr)
}

private fun initCustomAttibutes(attrs: AttributeSet?, defStyleAttr: Int) = with(binding) {
context.withStyledAttributes(attrs, R.styleable.CompoundViewContacts, defStyleAttr, 0) {
title.text = getString(R.styleable.CompoundViewContacts_contacts_title)
title.setTextColor(getColor(R.styleable.CompoundViewContacts_contacts_titleColor, 0))
text.text = getString(R.styleable.CompoundViewContacts_contacts_text)
text.setTextColor(getColor(R.styleable.CompoundViewContacts_contacts_textColor, 0))
binding.icon.setImageDrawable(getDrawable(R.styleable.CompoundViewContacts_contacts_icon))
binding.icon.setImageTintList(
ColorStateList.valueOf(
getColor(R.styleable.CompoundViewContacts_contacts_iconColor, 0)))
binding.divider.dividerColor = (getColor(R.styleable.CompoundViewContacts_contacts_dividerColor, 0))
}
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_address.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="#43474E"/>
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_arrow_back.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="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M3.825,9L9.425,14.6L8,16L0,8L8,0L9.425,1.4L3.825,7H16V9H3.825Z"
android:fillColor="#43474E"/>
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_attach.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="11dp"
android:height="20dp"
android:viewportWidth="11"
android:viewportHeight="20">
<path
android:pathData="M5.5,20C3.967,20 2.667,19.467 1.6,18.4C0.533,17.333 0,16.033 0,14.5V4C0,2.9 0.392,1.958 1.175,1.175C1.958,0.392 2.9,0 4,0C5.1,0 6.042,0.392 6.825,1.175C7.608,1.958 8,2.9 8,4V13.5C8,14.2 7.758,14.792 7.275,15.275C6.792,15.758 6.2,16 5.5,16C4.8,16 4.208,15.758 3.725,15.275C3.242,14.792 3,14.2 3,13.5V4H4.5V13.5C4.5,13.783 4.596,14.021 4.787,14.212C4.979,14.404 5.217,14.5 5.5,14.5C5.783,14.5 6.021,14.404 6.213,14.212C6.404,14.021 6.5,13.783 6.5,13.5V4C6.5,3.3 6.258,2.708 5.775,2.225C5.292,1.742 4.7,1.5 4,1.5C3.3,1.5 2.708,1.742 2.225,2.225C1.742,2.708 1.5,3.3 1.5,4V14.5C1.5,15.6 1.892,16.542 2.675,17.325C3.458,18.108 4.4,18.5 5.5,18.5C6.6,18.5 7.542,18.108 8.325,17.325C9.108,16.542 9.5,15.6 9.5,14.5V4H11V14.5C11,16.033 10.467,17.333 9.4,18.4C8.333,19.467 7.033,20 5.5,20Z"
android:fillColor="@color/on_surface_variant"/>
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_cancel.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="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M6.4,15L10,11.4L13.6,15L15,13.6L11.4,10L15,6.4L13.6,5L10,8.6L6.4,5L5,6.4L8.6,10L5,13.6L6.4,15ZM10,20C8.617,20 7.317,19.737 6.1,19.212C4.883,18.688 3.825,17.975 2.925,17.075C2.025,16.175 1.313,15.117 0.788,13.9C0.262,12.683 0,11.383 0,10C0,8.617 0.262,7.317 0.788,6.1C1.313,4.883 2.025,3.825 2.925,2.925C3.825,2.025 4.883,1.313 6.1,0.788C7.317,0.262 8.617,0 10,0C11.383,0 12.683,0.262 13.9,0.788C15.117,1.313 16.175,2.025 17.075,2.925C17.975,3.825 18.688,4.883 19.212,6.1C19.737,7.317 20,8.617 20,10C20,11.383 19.737,12.683 19.212,13.9C18.688,15.117 17.975,16.175 17.075,17.075C16.175,17.975 15.117,18.688 13.9,19.212C12.683,19.737 11.383,20 10,20ZM10,18C12.233,18 14.125,17.225 15.675,15.675C17.225,14.125 18,12.233 18,10C18,7.767 17.225,5.875 15.675,4.325C14.125,2.775 12.233,2 10,2C7.767,2 5.875,2.775 4.325,4.325C2.775,5.875 2,7.767 2,10C2,12.233 2.775,14.125 4.325,15.675C5.875,17.225 7.767,18 10,18Z"
android:fillColor="@color/on_surface_variant"/>
</vector>
Loading