blob: 9750f36943b6ba2e480c9bfb1b93e1f4e4537b88 [file] [log] [blame]
package com.android.car.docklib.view
import android.content.ComponentName
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.Point
import android.graphics.PorterDuff
import android.view.View
import androidx.core.view.setPadding
import androidx.recyclerview.widget.RecyclerView
import com.android.car.docklib.R
import com.android.car.docklib.data.DockAppItem
import com.google.android.material.imageview.ShapeableImageView
import java.util.function.Consumer
class DockItemViewHolder(
itemView: View,
private val intentDelegate: Consumer<Intent>,
) : RecyclerView.ViewHolder(itemView) {
companion object {
private const val DEFAULT_STROKE_WIDTH = 0f
}
private val staticIconStrokeWidth: Float
private val dynamicIconStrokeWidth: Float
private val excitedIconStrokeWidth: Float
private val iconStrokeColor: Int
private val excitedIconStrokeColor: Int
private val appIcon: ShapeableImageView
private var dockItemLongClickListener: DockItemLongClickListener? = null
private var iconStrokeWidth: Float = DEFAULT_STROKE_WIDTH
init {
staticIconStrokeWidth = itemView.resources.getDimension(R.dimen.static_icon_stroke_width)
dynamicIconStrokeWidth = itemView.resources.getDimension(R.dimen.dynamic_icon_stroke_width)
excitedIconStrokeWidth = itemView.resources.getDimension(R.dimen.icon_stroke_width_excited)
// todo(b/314859977): iconStrokeColor should be decided by the app primary color
iconStrokeColor = itemView.resources.getColor(
R.color.icon_default_stroke_color,
null // theme
)
excitedIconStrokeColor = itemView.resources.getColor(
R.color.icon_excited_stroke_color,
null // theme
)
appIcon = itemView.requireViewById(R.id.dock_app_icon)
}
fun bind(dockAppItem: DockAppItem?) {
reset()
if (dockAppItem == null) return
itemTypeChanged(dockAppItem)
appIcon.contentDescription = dockAppItem.name
appIcon.setImageDrawable(dockAppItem.icon)
appIcon.setOnClickListener {
val intent =
Intent(Intent.ACTION_MAIN)
.setComponent(dockAppItem.component)
.addCategory(Intent.CATEGORY_LAUNCHER)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intentDelegate.accept(intent)
}
dockItemLongClickListener = DockItemLongClickListener(
dockAppItem,
pinItemClickDelegate =
{ (bindingAdapter as? DockAdapter)?.pinItemAt(bindingAdapterPosition) },
unpinItemClickDelegate =
{ (bindingAdapter as? DockAdapter)?.unpinItemAt(bindingAdapterPosition) }
)
appIcon.onLongClickListener = dockItemLongClickListener
itemView.setOnDragListener(
DockDragListener(
viewHolder = this,
object : DockDragListener.Callback {
override fun dragAccepted(componentName: ComponentName) {
pinNewItem(componentName)
}
override fun exciteView() {
exciteAppIcon()
}
override fun resetView() {
resetAppIcon()
}
override fun getDropContainerLocation(): Point {
val containerLocation = itemView.locationOnScreen
return Point(containerLocation[0], containerLocation[1])
}
override fun getDropLocation(): Point {
val iconLocation = appIcon.locationOnScreen
return Point(
(iconLocation[0] + iconStrokeWidth.toInt()),
(iconLocation[1] + iconStrokeWidth.toInt())
)
}
override fun getDropWidth(): Float {
return (appIcon.width.toFloat() - iconStrokeWidth * 2)
}
override fun getDropHeight(): Float {
return (appIcon.height.toFloat() - iconStrokeWidth * 2)
}
}
)
)
}
fun itemTypeChanged(dockAppItem: DockAppItem) {
iconStrokeWidth = when (dockAppItem.type) {
DockAppItem.Type.STATIC -> staticIconStrokeWidth
DockAppItem.Type.DYNAMIC -> dynamicIconStrokeWidth
}
appIcon.strokeWidth = iconStrokeWidth
appIcon.invalidate()
dockItemLongClickListener?.setDockAppItem(dockAppItem)
}
private fun pinNewItem(componentName: ComponentName) {
(bindingAdapter as? DockAdapter)?.pinItemAt(bindingAdapterPosition, componentName)
}
private fun exciteAppIcon() {
// todo(b/312737692): add animations
appIcon.strokeColor = ColorStateList.valueOf(excitedIconStrokeColor)
appIcon.setColorFilter(Color.argb(0.3f, 0f, 0f, 0f), PorterDuff.Mode.DARKEN)
appIcon.strokeWidth = excitedIconStrokeWidth
appIcon.setPadding(getPaddingFromStrokeWidth(excitedIconStrokeWidth))
appIcon.invalidate()
}
private fun resetAppIcon() {
appIcon.strokeColor = ColorStateList.valueOf(iconStrokeColor)
appIcon.colorFilter = null
appIcon.strokeWidth = iconStrokeWidth
appIcon.setPadding(getPaddingFromStrokeWidth(iconStrokeWidth))
appIcon.invalidate()
}
private fun reset() {
iconStrokeWidth = DEFAULT_STROKE_WIDTH
resetAppIcon()
appIcon.contentDescription = null
appIcon.setImageDrawable(null)
appIcon.setOnClickListener(null)
itemView.setOnDragListener(null)
}
private fun getPaddingFromStrokeWidth(strokeWidth: Float): Int = (strokeWidth / 2).toInt()
// TODO: b/301484526 Add animation when app icon is changed
}