mirror of
https://github.com/Michatec/Radio.git
synced 2026-04-01 07:56:27 +02:00
Initial commit
This commit is contained in:
282
app/src/main/java/com/michatec/radio/helpers/UiHelper.kt
Normal file
282
app/src/main/java/com/michatec/radio/helpers/UiHelper.kt
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* UiHelper.kt
|
||||
* Implements the UiHelper object
|
||||
* A UiHelper provides helper methods for User Interface related tasks
|
||||
*
|
||||
* This file is part of
|
||||
* TRANSISTOR - Radio App for Android
|
||||
*
|
||||
* Copyright (c) 2015-22 - Y20K.org
|
||||
* Licensed under the MIT-License
|
||||
* http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
|
||||
package com.michatec.radio.helpers
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffXfermode
|
||||
import android.graphics.RectF
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.michatec.radio.Keys
|
||||
import com.michatec.radio.R
|
||||
|
||||
|
||||
/*
|
||||
* UiHelper object
|
||||
*/
|
||||
object UiHelper {
|
||||
|
||||
/* Sets layout margins for given view in DP */
|
||||
fun setViewMargins(
|
||||
context: Context,
|
||||
view: View,
|
||||
left: Int = 0,
|
||||
right: Int = 0,
|
||||
top: Int = 0,
|
||||
bottom: Int = 0
|
||||
) {
|
||||
val l: Int = (left * ImageHelper.getDensityScalingFactor(context)).toInt()
|
||||
val r: Int = (right * ImageHelper.getDensityScalingFactor(context)).toInt()
|
||||
val t: Int = (top * ImageHelper.getDensityScalingFactor(context)).toInt()
|
||||
val b: Int = (bottom * ImageHelper.getDensityScalingFactor(context)).toInt()
|
||||
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
|
||||
val p = view.layoutParams as ViewGroup.MarginLayoutParams
|
||||
p.setMargins(l, t, r, b)
|
||||
view.requestLayout()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Hide keyboard */
|
||||
fun hideSoftKeyboard(context: Context, view: View) {
|
||||
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Inner class: Callback that detects a swipe to left
|
||||
* Credit: https://github.com/kitek/android-rv-swipe-delete/blob/master/app/src/main/java/pl/kitek/rvswipetodelete/SwipeToDeleteCallback.kt
|
||||
*/
|
||||
abstract class SwipeToDeleteCallback(context: Context) :
|
||||
ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
|
||||
|
||||
private val deleteIcon = ContextCompat.getDrawable(context, R.drawable.ic_remove_circle_24dp)
|
||||
private val intrinsicWidth: Int = deleteIcon?.intrinsicWidth ?: 0
|
||||
private val intrinsicHeight: Int = deleteIcon?.intrinsicHeight ?: 0
|
||||
private val backgroundColor = ContextCompat.getColor(context, R.color.list_card_delete_background)
|
||||
private val clearPaint: Paint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) }
|
||||
private val cornerRadius: Float = dpToPx(context)
|
||||
|
||||
override fun getMovementFlags(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
): Int {
|
||||
// disable swipe for the add new card
|
||||
if (viewHolder.itemViewType == Keys.VIEW_TYPE_ADD_NEW) {
|
||||
return 0
|
||||
}
|
||||
return super.getMovementFlags(recyclerView, viewHolder)
|
||||
}
|
||||
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
// do nothing
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onChildDraw(
|
||||
c: Canvas,
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
dX: Float,
|
||||
dY: Float,
|
||||
actionState: Int,
|
||||
isCurrentlyActive: Boolean
|
||||
) {
|
||||
val itemView = viewHolder.itemView
|
||||
val itemHeight = itemView.bottom - itemView.top
|
||||
val isCanceled = dX == 0f && !isCurrentlyActive
|
||||
|
||||
if (isCanceled) {
|
||||
clearCanvas(
|
||||
c,
|
||||
itemView.right + dX,
|
||||
itemView.top.toFloat(),
|
||||
itemView.right.toFloat(),
|
||||
itemView.bottom.toFloat()
|
||||
)
|
||||
super.onChildDraw(
|
||||
c,
|
||||
recyclerView,
|
||||
viewHolder,
|
||||
dX,
|
||||
dY,
|
||||
actionState,
|
||||
false
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// draw delete and rounded background
|
||||
val roundedBackground = RectF(
|
||||
itemView.left.toFloat(),
|
||||
itemView.top.toFloat(),
|
||||
itemView.right.toFloat(),
|
||||
itemView.bottom.toFloat()
|
||||
)
|
||||
|
||||
val paint = Paint()
|
||||
paint.color = backgroundColor
|
||||
c.drawRoundRect(roundedBackground, cornerRadius, cornerRadius, paint)
|
||||
|
||||
// calculate position of delete icon
|
||||
val deleteIconTop = itemView.top + (itemHeight - intrinsicHeight) / 2
|
||||
val deleteIconMargin = (itemHeight - intrinsicHeight) / 2
|
||||
val deleteIconLeft = itemView.right - deleteIconMargin - intrinsicWidth
|
||||
val deleteIconRight = itemView.right - deleteIconMargin
|
||||
val deleteIconBottom = deleteIconTop + intrinsicHeight
|
||||
|
||||
// draw delete icon
|
||||
deleteIcon?.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom)
|
||||
deleteIcon?.draw(c)
|
||||
|
||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
|
||||
}
|
||||
|
||||
private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) {
|
||||
c?.drawRect(left, top, right, bottom, clearPaint)
|
||||
}
|
||||
|
||||
// conversion from dp to px
|
||||
private fun dpToPx(context: Context): Float {
|
||||
val density = context.resources.displayMetrics.density
|
||||
return 24 * density
|
||||
}
|
||||
}
|
||||
/*
|
||||
* End of inner class
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Inner class: Callback that detects a swipe to left
|
||||
* Credit: https://github.com/kitek/android-rv-swipe-delete/blob/master/app/src/main/java/pl/kitek/rvswipetodelete/SwipeToDeleteCallback.kt
|
||||
*/
|
||||
abstract class SwipeToMarkStarredCallback(context: Context) :
|
||||
ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
|
||||
|
||||
private val starIcon = ContextCompat.getDrawable(context, R.drawable.ic_favorite_24dp)
|
||||
private val intrinsicWidth: Int = starIcon?.intrinsicWidth ?: 0
|
||||
private val intrinsicHeight: Int = starIcon?.intrinsicHeight ?: 0
|
||||
private val backgroundColor = ContextCompat.getColor(context, R.color.list_card_mark_starred_background)
|
||||
private val clearPaint: Paint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) }
|
||||
private val cornerRadius: Float = dpToPx(context)
|
||||
|
||||
override fun getMovementFlags(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
): Int {
|
||||
// disable swipe for the add new card
|
||||
if (viewHolder.itemViewType == Keys.VIEW_TYPE_ADD_NEW) {
|
||||
return 0
|
||||
}
|
||||
return super.getMovementFlags(recyclerView, viewHolder)
|
||||
}
|
||||
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
// do nothing
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onChildDraw(
|
||||
c: Canvas,
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
dX: Float,
|
||||
dY: Float,
|
||||
actionState: Int,
|
||||
isCurrentlyActive: Boolean
|
||||
) {
|
||||
val itemView = viewHolder.itemView
|
||||
val itemHeight = itemView.bottom - itemView.top
|
||||
val isCanceled = dX == 0f && !isCurrentlyActive
|
||||
|
||||
if (isCanceled) {
|
||||
clearCanvas(
|
||||
c,
|
||||
itemView.right + dX,
|
||||
itemView.top.toFloat(),
|
||||
itemView.right.toFloat(),
|
||||
itemView.bottom.toFloat()
|
||||
)
|
||||
super.onChildDraw(
|
||||
c,
|
||||
recyclerView,
|
||||
viewHolder,
|
||||
dX,
|
||||
dY,
|
||||
actionState,
|
||||
false
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// draw favorite color and rounded background
|
||||
val roundedBackground = RectF(
|
||||
itemView.left.toFloat(),
|
||||
itemView.top.toFloat(),
|
||||
itemView.right.toFloat(),
|
||||
itemView.bottom.toFloat()
|
||||
)
|
||||
|
||||
val paint = Paint()
|
||||
paint.color = backgroundColor
|
||||
c.drawRoundRect(roundedBackground, cornerRadius, cornerRadius, paint)
|
||||
|
||||
// calculate position of delete icon
|
||||
val deleteIconTop = itemView.top + (itemHeight - intrinsicHeight) / 2
|
||||
val deleteIconMargin = (itemHeight - intrinsicHeight) / 2
|
||||
val deleteIconLeft = itemView.left + deleteIconMargin
|
||||
val deleteIconRight = itemView.left + deleteIconMargin + intrinsicWidth
|
||||
val deleteIconBottom = deleteIconTop + intrinsicHeight
|
||||
|
||||
// draw delete icon
|
||||
starIcon?.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom)
|
||||
starIcon?.draw(c)
|
||||
|
||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
|
||||
}
|
||||
|
||||
private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) {
|
||||
c?.drawRect(left, top, right, bottom, clearPaint)
|
||||
}
|
||||
|
||||
// conversion from dp to px
|
||||
private fun dpToPx(context: Context): Float {
|
||||
val density = context.resources.displayMetrics.density
|
||||
return 24 * density
|
||||
}
|
||||
}
|
||||
/*
|
||||
* End of inner class
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user