Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
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 3 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 109 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 11 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 9 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 9 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 9 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 9 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
Morty Proxy This is a proxified and sanitized view of the page, visit original site.