diff --git a/app/build.gradle b/app/build.gradle index 8df24ea..e5c65f7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,6 +29,9 @@ android { kotlinOptions { jvmTarget = '1.8' } + viewBinding { + enabled = true + } } dependencies { diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/CartActivity.kt b/app/src/main/java/otus/gpb/homework/viewandresources/CartActivity.kt index b6cbf73..938868e 100644 --- a/app/src/main/java/otus/gpb/homework/viewandresources/CartActivity.kt +++ b/app/src/main/java/otus/gpb/homework/viewandresources/CartActivity.kt @@ -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 + 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(R.id.recyclerView) + textCartOrderTotal = findViewById(R.id.textCartOrderTotal) + textCartSubtotal = findViewById(R.id.textCartSubtotal) + textCartShipping = findViewById(R.id.textCartShipping) + textCartTax = findViewById(R.id.textCartTax) + textCartItemCount = findViewById(R.id.textCartItemCount) + textCartOrderTotalAmount = findViewById(R.id.textCartOrderTotalAmount) + textCartSubtotalAmount = findViewById(R.id.textCartSubtotalAmount) + textCartShippingAmount = findViewById(R.id.textCartShippingAmount) + textCartTaxAmount = findViewById(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 { + 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() + 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) } } \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/CartItem.kt b/app/src/main/java/otus/gpb/homework/viewandresources/CartItem.kt new file mode 100644 index 0000000..02a8e32 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/viewandresources/CartItem.kt @@ -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, + ) \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/CartItemAdapter.kt b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemAdapter.kt new file mode 100644 index 0000000..c402d46 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemAdapter.kt @@ -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() { + + private lateinit var list: MutableList + + 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) { + list = items + notifyItemInserted(0) + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/CartItemListener.kt b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemListener.kt new file mode 100644 index 0000000..209db8b --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemListener.kt @@ -0,0 +1,7 @@ +package otus.gpb.homework.viewandresources + +interface CartItemListener { + fun onItemClick(item: CartItem) + fun onItemSwiped(item: CartItem) + fun onLoadMoreItem() +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/CartItemTouchHelper.kt b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemTouchHelper.kt new file mode 100644 index 0000000..5b4e112 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemTouchHelper.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/viewandresources/CartItemViewHolder.kt b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemViewHolder.kt new file mode 100644 index 0000000..140e44a --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/viewandresources/CartItemViewHolder.kt @@ -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(R.id.cart_item_container) + private var image = view.findViewById(R.id.cart_item_image) + private var price = view.findViewById(R.id.cart_item_price) + private var caption = view.findViewById(R.id.cart_item_caption) + private var category = view.findViewById(R.id.cart_item_category) + private var description = view.findViewById(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 + } +} \ 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..7b7b70d 100644 --- a/app/src/main/java/otus/gpb/homework/viewandresources/MainActivity.kt +++ b/app/src/main/java/otus/gpb/homework/viewandresources/MainActivity.kt @@ -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() { @@ -21,6 +22,7 @@ class MainActivity : AppCompatActivity() { findViewById