Snippets Collections
package adapter

import android.content.Context
import android.view.ViewGroup
import androidx.collection.SparseArrayCompat
import androidx.recyclerview.widget.RecyclerView
import domain.ViewType
import domain.movie.ListaItemFilme
import pessoaspopulares.adapter.LoadingDelegateAdapter
import pessoaspopulares.adapter.ViewTypeDelegateAdapter
import utils.Constant

/**
 * Created by icaro on 14/08/16.
 */
class ListUserAdapter(private val context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    private val listaResult = ArrayList<ViewType>()
    private val delegateAdapters = SparseArrayCompat<ViewTypeDelegateAdapter>()

    init {
        delegateAdapters.put(Constant.ViewTypesIds.LOADING, LoadingDelegateAdapter())
        delegateAdapters.put(Constant.ViewTypesIds.NEWS, ListasDelegateAdapter())
        listaResult.add(loading)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return delegateAdapters.get(viewType)!!.onCreateViewHolder(parent)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        delegateAdapters.get(getItemViewType(position))?.onBindViewHolder(holder, listaResult[position], context)
    }

    override fun getItemViewType(position: Int): Int {
        return listaResult[position].getViewType()
    }

    fun addItens(listaMedia: List<ListaItemFilme?>?, totalResults: Int) {
        if (listaMedia?.isNotEmpty()!!) {
            val initPosition = listaResult.size - 1
            this.listaResult.removeAt(initPosition)
            notifyItemRemoved(initPosition)
            for (result in listaMedia) {
                this.listaResult.add(result!!)
            }
            this.listaResult.sortedBy { (it as ListaItemFilme).releaseDate }
                .reversed()
            notifyItemRangeChanged(initPosition, this.listaResult.size + 1 /* plus loading item */)
            if (listaResult.size < totalResults)
                this.listaResult.add(loading)
        }
    }

    override fun getItemCount(): Int = listaResult.size

    companion object {

        private val loading = object : ViewType {
            override fun getViewType(): Int {
                return Constant.ViewTypesIds.LOADING
            }
        }
    }
}





@Keep
interface ViewType {
    fun getViewType(): Int
}

interface ViewTypeDelegateAdapter {

    fun onCreateViewHolder(parent: ViewGroup): RecyclerView.ViewHolder

    fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType?, context: Context?)
}



class LoadingDelegateAdapter : ViewTypeDelegateAdapter {

    override fun onCreateViewHolder(parent: ViewGroup) = LoadingViewHolder(parent)

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType?, context: Context?) {
    }

    class LoadingViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
            LayoutInflater.from(parent.context)
                .inflate(R.layout.new_item_loading, parent, false))
}


class ListasDelegateAdapter : ViewTypeDelegateAdapter {

	override fun onCreateViewHolder(parent: ViewGroup): RecyclerView.ViewHolder =
		ListViewHolder(parent)

	override fun onBindViewHolder(
		holder: RecyclerView.ViewHolder,
		item: ViewType?,
		context: Context?
	) {
		(holder as ListViewHolder).bind(item as ListaItemFilme)
	}

	inner class ListViewHolder(parent: ViewGroup) :
		RecyclerView.ViewHolder(
			LayoutInflater.from(parent.context).inflate(R.layout.lista, parent, false)
		) {

		fun bind(item: ListaItemFilme) = with(itemView) {

			img_lista.setPicassoWithCache(item.posterPath, 3)
			when (item.mediaType) {
				"tv" -> date_oscar.text =
					if (!item.first_air_date.isNullOrEmpty() && item.first_air_date.length > 3)
						item.first_air_date.subSequence(0, 4) else "-"
				"movie" -> date_oscar.text =
					if (!item.releaseDate.isNullOrEmpty() && item.releaseDate.length > 3)
						item.releaseDate.subSequence(0, 4) else "-"
			}

			progress.visibility = View.GONE
			itemView.setOnClickListener {
				when (item.mediaType) {
					"tv" -> {
						val intent = Intent(context, TvShowActivity::class.java).apply {
							putExtra(Constant.TVSHOW_ID, item.id)
							putExtra(Constant.COLOR_TOP, UtilsApp.loadPalette(img_lista))
						}
						context.startActivity(intent)
					}
					"movie" -> {
						val intent = Intent(context, MovieDetailsActivity::class.java).apply {
							putExtra(Constant.FILME_ID, item.id)
							putExtra(Constant.COLOR_TOP, UtilsApp.loadPalette(img_lista))
						}
						context.startActivity(intent)
					}
				}
			}
		}
	}
}

  
package utils

import android.animation.Animator
import android.animation.Animator.*
import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.drawable.BitmapDrawable
import android.util.Log
import android.view.View
import android.view.ViewGroup.*
import android.widget.ImageView
import android.widget.Toast
import androidx.core.view.marginTop
import androidx.fragment.app.FragmentActivity
import androidx.palette.graphics.Palette
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import applicaton.BaseViewModel.*
import applicaton.BaseViewModel.BaseRequest.*
import br.com.icaro.filme.R
import com.github.clans.fab.FloatingActionMenu
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.gson.Gson
import com.squareup.picasso.Callback
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.NetworkPolicy
import com.squareup.picasso.Picasso
import domain.reelgood.movie.Availability
import domain.tvshow.Tvshow
import error.BottomSheetError
import error.CallBackError
import java.text.DateFormat
import java.text.Normalizer
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

/**
 * Created by icaro on 03/09/17.
 */
/**
 * IMAGEVIEW
 */
fun ImageView.setPicasso(
	stillPath: String?,
	patten: Int = 4,
	sucesso: () -> Unit = {},
	error: () -> Unit = {},
	img_erro: Int = R.drawable.poster_empty,
): ImageView {
	Picasso.get()
		.load(
			UtilsApp
				.getBaseUrlImagem(UtilsApp.getTamanhoDaImagem(context, patten)) + stillPath
		)
		.error(img_erro)
		.memoryPolicy(MemoryPolicy.NO_STORE, MemoryPolicy.NO_CACHE)
		.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
		.into(this, object : Callback {
			override fun onSuccess() {
				sucesso()
			}

			override fun onError(e: java.lang.Exception?) {
				error()
			}
		})
	return this
}

fun ImageView.setPicassoWithCache(
	stillPath: String?, patten: Int = 4,
	sucesso: () -> Unit = {},
	error: () -> Unit = {},
	img_erro: Int = R.drawable.poster_empty,
): ImageView {
	Picasso.get()
		.load(
			UtilsApp
				.getBaseUrlImagem(UtilsApp.getTamanhoDaImagem(context, patten)) + stillPath
		)
		.error(img_erro)
		.into(this, object : Callback {
			override fun onSuccess() {
				sucesso()
			}

			override fun onError(e: java.lang.Exception?) {
				error()
			}
		})
	return this
}

fun ImageView.setPicassoWithCacheAndHolder(
	stillPath: String?, patten: Int = 4,
	sucesso: () -> Unit = {},
	error: () -> Unit = {},
	img_erro: Int = R.drawable.poster_empty,
	holder: Int,
): ImageView {
	Picasso.get()
		.load(UtilsApp.getBaseUrlImagem(UtilsApp.getTamanhoDaImagem(context, patten)) + stillPath)
		.placeholder(holder)
		.error(img_erro)
		.into(this, object : Callback {
			override fun onSuccess() {
				sucesso()
			}

			override fun onError(e: java.lang.Exception?) {
				error()
			}
		})
	return this
}

fun ImageView.loadPallet(): Int? {
	val color = (drawable as? BitmapDrawable)?.run {
		Palette.Builder(this.bitmap).generate().swatches.first().rgb
	}
	return color ?: 0
}

fun loadPalette(view: ImageView): Int { // Todo Usar ext
	val imageView = view as ImageView
	val drawable = imageView.drawable as? BitmapDrawable
	if (drawable != null) {
		return Palette.Builder(drawable.bitmap).generate().swatches.last().rgb
	}
	return 0
}

/**
 * ACTIVITY
 */
fun Activity.makeToast(restText: Int, time: Int = Toast.LENGTH_SHORT) {
	this.makeToast(this.getString(restText), time)
}

fun Activity.makeToast(text: String?, time: Int = Toast.LENGTH_SHORT) {
	Toast.makeText(this, text, time).show()
}

/**
 * Context
 */
fun Context.makeToast(text: String?, time: Int = Toast.LENGTH_SHORT) {
	Toast.makeText(this, text, time).show()
}

/**
 * VIEW
 */
fun View.gone() {
	this.visibility = View.GONE
}

fun View.visible() {
	this.visibility = View.VISIBLE
}

fun View.invisible() {
	this.visibility = View.INVISIBLE
}

fun View.animeRotation(
	end: () -> Unit = {},
	cancel: () -> Unit = {},
	start: () -> Unit = {},
	repeat: () -> Unit = {},
) {
	ObjectAnimator
		.ofPropertyValuesHolder(
			this,
			PropertyValuesHolder.ofFloat(View.SCALE_X, 1.0f, 0.2f),
			PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.0f, 0.2f),
			PropertyValuesHolder.ofFloat(View.SCALE_X, 0.0f, 1.0f),
			PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.0f, 1.0f)
		)
		.apply {
			duration = 790
			addListener(object : AnimatorListener {
				override fun onAnimationRepeat(animation: Animator?) {
					repeat()
				}

				override fun onAnimationEnd(animation: Animator?) {
					end()
				}

				override fun onAnimationCancel(animation: Animator?) {
					cancel()
				}

				override fun onAnimationStart(animation: Animator?) {
					start()
				}
			})
		}.start()
}

/**
 * Any
 */
fun Any.putString(cxt: Context): String = when (this) {
	is String -> this
	is Int -> cxt.getString(this)
	else -> {
		require(false) { "Need R.string.id or string" }
		""
	}
}

/**
 * STRING
 */
fun String.removerAcentos(): String {
	this.replace(".", "")
	this.replace(":", "")
	this.replace("/", "")
	this.replace(";", "")
	return Normalizer.normalize(this, Normalizer.Form.NFD).replace("[^\\p{ASCII}]".toRegex(), "")
}

fun String.parseDate(): String {
	return try {
		val sim = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
		val data = sim.parse(this)
		DateFormat.getDateInstance(DateFormat.SHORT).format(data)
	} catch (ex: Exception) {
		"-/-"
	}
}

fun String.parseDateShot(): String {
	return try {
		val sim = SimpleDateFormat("yyyy-MM-dd")
		val data = sim.parse(this)
		DateFormat.getDateInstance(DateFormat.SHORT).format(data)
	} catch (ex: Exception) {
		"-/-"
	}
}

fun verifyLaunch(air_date: Date?): Boolean {
	if (air_date == null) return false
	val now = Calendar.getInstance().time
	return if (air_date.before(now)) {
		true
	} else !air_date.after(now)
}

fun String.getDate(format: String = "yyyy-MM-dd"): Date? {
	return try {
		let {
			val sdf = SimpleDateFormat(format, Locale.getDefault())
			sdf.parse(it)
		}
	} catch (e: ParseException) {
		e.printStackTrace()
		null
	}
}

fun String.released(): Boolean {
	val data = getDate()
	return verifyLaunch(data)
}

@Throws(Exception::class)
fun String.yearDate(): String {
	return if (this.length >= 4) this.substring(0, 4) else ""
}

fun String.periodLaunch(): Boolean {
	val oneWeekBack = Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, -7) }.time
	return getDate() != null && getDate()!!.after(oneWeekBack) //valida data
}

fun String.getNameTypeReel(): String {
	return replace(":", "-")
		.replace(" ", "-")
		.replace("&", "and")
		.replace(".", "")
		.replace("é", "e")
		.replace("ẽ", "e")
		.replace("è", "e")
		.replace("ë", "e")
		.replace("ç", "c")
		.replace("â", "a")
		.replace("ã", "a")
		.replace("á", "a")
		.replace("à", "a")
		.replace("ä", "a")
		.replace("ä", "a")
		.replace("'", "")
		.replace("\"", "")
		.replace("´", "")
		.replace("~", "")
		.replace("^", "")
		.replace("---", "-")
		.replace("----", "-")
		.replace("--", "-")
		.toLowerCase()
}

fun String?.notNullOrEmpty() = !this.isNullOrEmpty()
fun <T> Gson.fromJsonWithLog(json: String?, classOfT: Class<T>): T {
	return this.fromJson<T>(json, classOfT).apply {
		this.toString().log(classOfT.name)
	}
}

fun String.log(tag: String = "") = Log.i(tag, this)

fun Tvshow.createIdReal() = createIdReal(this.originalName ?: "", this.firstAirDate ?: "")
private fun createIdReal(originalName: String, data: String) =
	"${originalName.getNameTypeReel()}-${data.yearDate()}"

/**
 * RECYCLER
 */
fun RecyclerView.setScrollInvisibleFloatMenu(floatButton: FloatingActionMenu) {
	addOnScrollListener(object : RecyclerView.OnScrollListener() {
		override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
			when (newState) {
				RecyclerView.SCROLL_STATE_IDLE -> floatButton.visible()
				RecyclerView.SCROLL_STATE_DRAGGING -> floatButton.invisible()
				RecyclerView.SCROLL_STATE_SETTLING -> floatButton.invisible()
			}
		}
	})
}

@SuppressLint("WrongConstant")
fun RecyclerView.patternRecyler(horizont: Boolean = true): RecyclerView {
	val typeOrient = if (horizont) LinearLayoutManager.HORIZONTAL else LinearLayoutManager.VERTICAL
	layoutManager = LinearLayoutManager(context, typeOrient, false)
	itemAnimator = DefaultItemAnimator()
	setHasFixedSize(true)
	return this
}

fun RecyclerView.patternRecyclerGrid(quant: Int = 2): RecyclerView {
	layoutManager = GridLayoutManager(context, quant)
	setHasFixedSize(true)
	itemAnimator = DefaultItemAnimator()
	return this
}

fun RecyclerView.minHeight(): RecyclerView {
	layoutParams.height = 1
	importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
	isFocusable = false
	return this
}

/**
 * AVAILABILITY
 */
fun Availability.getPricePurchase(): String {
	val less = purchaseCostSd?.let { purchaseCostHd?.coerceAtMost(it) }
	val biggest = purchaseCostSd?.let { purchaseCostHd?.coerceAtLeast(it) }
	if (less == biggest) return less.toString()
	return "${if (less != 0.0) less.toString() else "--"} - ${if (biggest != 0.0) biggest.toString() else "--"}"
}

fun Availability.getPriceRental(): String {
	val less = rentalCostSd?.let { rentalCostHd?.coerceAtMost(it) }
	val biggest = rentalCostSd?.let { rentalCostHd?.coerceAtLeast(it) }
	if (less == biggest) return less.toString()
	return "${if (less != 0.0) less.toString() else "--"} - ${if (biggest != 0.0) biggest.toString() else "--"}"
}

/**
 * BottomSheetBehavior
 */
fun BottomSheetBehavior<View>.setAnimation(container: View, viewHeight: View) {
	ValueAnimator.ofInt(container.measuredHeight, viewHeight.marginTop).apply {
		addUpdateListener {
			peekHeight = it.animatedValue as Int
		}
		duration = 500
	}.start()

	container.post {
		val newLayoutParams = (container.layoutParams as? MarginLayoutParams)
		newLayoutParams?.setMargins(0, 0, 0, viewHeight.marginTop + 1)
		container.layoutParams = newLayoutParams
	}
}

/**
 * MutableList
 */
fun <T> MutableList<T>.replaceItemList(item: T, predicate: (T) -> Boolean): MutableList<T> {
	return this.map {
		if (predicate(it)) item else it
	}.toMutableList()
}

fun <T> Any.listSize(item: T, size: Int): ArrayList<T> {
	return if (size <= 0) {
		arrayListOf()
	} else {
		arrayListOf<T>().apply {
			for (i in 0 until size) {
				add(item)
			}
		}
	}
}

/**
 * BaseRequest
 */
fun <T> BaseRequest<T>.success() = (this as Success<T>).result
fun <T> BaseRequest<T>.resolver(
	activity: FragmentActivity,
	successBlock: (data: T) -> Unit,
	failureBlock: (error: Exception) -> Unit = {},
	loadingBlock: (loading: Boolean) -> Unit = {},
	genericError: CallBackError? = null,
) {
	when (this) {
		is Success -> successBlock(result)
		is Loading -> loadingBlock(loading)
		is Failure -> {
			error.toString().log()
			if (genericError != null) {
				BottomSheetError().newInstance(callBackError = genericError)
					.show(activity.supportFragmentManager, "")
			} else {
				failureBlock(error)
			}
		}
	}
}


import android.animation.Animator
import android.animation.Animator.*
import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.animation.ValueAnimator
import android.app.Activity
import android.content.Context
import android.graphics.PorterDuff
import android.util.Log
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.*
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.Toast
import androidx.annotation.ColorRes
import androidx.appcompat.widget.AppCompatSpinner
import androidx.core.content.ContextCompat
import androidx.core.view.children
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import br.gov.sp.educacao.diariodeclassesp.BaseActivity
import br.gov.sp.educacao.diariodeclassesp.BaseViewModel.*
import br.gov.sp.educacao.diariodeclassesp.BaseViewModel.BaseRequest.*
import br.gov.sp.educacao.diariodeclassesp.R
import br.gov.sp.educacao.diariodeclassesp.models.ResponseDiario
import br.gov.sp.educacao.diariodeclassesp.utils.ToastDiario
import br.gov.sp.educacao.diariodeclassesp.utils.ToastDiario.Type.*
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.navigation.NavigationView
import com.google.gson.Gson
import com.squareup.picasso.Callback
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.NetworkPolicy
import com.squareup.picasso.Picasso
import okhttp3.Response
import org.json.JSONObject
import java.text.DateFormat
import java.text.Normalizer
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.ArrayList
import java.util.Calendar
import java.util.Date
import java.util.Locale

/**
 * Created by icaro on 03/09/17.
 */
/**
 * IMAGEVIEW
 */
fun ImageView.setPicasso(
	stillPath: String?,
	sucesso: () -> Unit = {},
	error: () -> Unit = {},
	img_erro: Int = R.drawable.apagar_snape
): ImageView {
	Picasso.get()
		.load(stillPath)
		.error(img_erro)
		.memoryPolicy(MemoryPolicy.NO_STORE, MemoryPolicy.NO_CACHE)
		.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
		.into(this, object : Callback {
			override fun onSuccess() {
				sucesso()
			}

			override fun onError(e: java.lang.Exception?) {
				error()
			}
		})
	return this
}

fun ImageView.setPicassoWithCache(
	stillPath: String?,
	sucesso: () -> Unit = {},
	error: () -> Unit = {},
	img_erro: Int = R.drawable.apagar_snape
): ImageView {
	Picasso.get()
		.load(stillPath)
		.error(img_erro)
		.into(this, object : Callback {
			override fun onSuccess() {
				sucesso()
			}

			override fun onError(e: java.lang.Exception?) {
				error()
			}
		})
	return this
}

fun ImageView.setPicassoWithCacheAndHolder(
	stillPath: String?,
	sucesso: () -> Unit = {},
	error: () -> Unit = {},
	img_erro: Int = R.drawable.apagar_snape,
	holder: Int
): ImageView {
	Picasso.get()
		.load(stillPath)
		.placeholder(holder)
		.error(img_erro)
		.into(this, object : Callback {
			override fun onSuccess() {
				sucesso()
			}

			override fun onError(e: java.lang.Exception?) {
				error()
			}
		})
	return this
}

fun ImageView.setSvgColor(@ColorRes color: Int) =
	setColorFilter(ContextCompat.getColor(context, color), PorterDuff.Mode.SRC_IN)
/**
 * CONTEXT
 */

fun Context.makeToast(restText: Int, time: Int = Toast.LENGTH_SHORT) {
	this.makeToast(this.getString(restText), time)
}

fun Context.makeToast(text: String?, time: Int = Toast.LENGTH_SHORT) {
	Toast.makeText(this, text, time).show()
}

/**
 * ACTIVITY
 */
fun Activity.makeToast(restText: Int, time: Int = Toast.LENGTH_SHORT) {
	this.makeToast(this.getString(restText), time)
}

fun Activity.makeToast(text: String?, time: Int = Toast.LENGTH_SHORT) {
	Toast.makeText(this, text, time).show()
}

fun Activity.hideSoftKeyboard() {
	window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
	val imm: InputMethodManager =
		getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
	currentFocus.ifValid {
		imm.hideSoftInputFromWindow(currentFocus!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
	}
}

/**
 * FRAGMENT
 */
fun Fragment.makeToast(restText: Int, time: Int = Toast.LENGTH_SHORT) {
	this.makeToast(this.getString(restText), time)
}

fun Fragment.makeToast(text: String?, time: Int = Toast.LENGTH_SHORT) {
	Toast.makeText(requireContext(), text, time).show()
}

fun Fragment.hideSoftKeyboard() {
	requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
}

/**
 * VIEW
 */
fun View.gone() {
	this.visibility = View.GONE
}

fun View.visible() {
	this.visibility = View.VISIBLE
}

fun View.invisible() {
	this.visibility = View.INVISIBLE
}

fun View.onClick(func: () -> Unit) = this.apply { setOnClickListener { func.invoke() } }

fun View.animeRotation(
	end: () -> Unit = {},
	cancel: () -> Unit = {},
	start: () -> Unit = {},
	repeat: () -> Unit = {}
) {
	ObjectAnimator
		.ofPropertyValuesHolder(
			this,
			PropertyValuesHolder.ofFloat(View.SCALE_X, 1.0f, 0.2f),
			PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.0f, 0.2f),
			PropertyValuesHolder.ofFloat(View.SCALE_X, 0.0f, 1.0f),
			PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.0f, 1.0f)
		)
		.apply {
			duration = 790
			addListener(object : AnimatorListener {
				override fun onAnimationRepeat(animation: Animator?) {
					repeat()
				}

				override fun onAnimationEnd(animation: Animator?) {
					end()
				}

				override fun onAnimationCancel(animation: Animator?) {
					cancel()
				}

				override fun onAnimationStart(animation: Animator?) {
					start()
				}
			})
		}.start()
}

/**
 * Any
 */
fun Any.putString(cxt: Context): String = when (this) {
	is String -> this
	is Int -> cxt.getString(this)
	else -> {
		require(false) { "Need R.string.id or string" }
		""
	}
}

fun <T> Any.listSize(item: T, size: Int): ArrayList<T> {
	return if (size <= 0) {
		arrayListOf()
	} else {
		arrayListOf<T>().apply {
			for (i in 0 until size) {
				add(item)
			}
		}
	}
}

/**
 * STRING
 */
fun String.removerAcentos(): String {
	this.replace(".", "")
	this.replace(":", "")
	this.replace("/", "")
	this.replace(";", "")
	return Normalizer.normalize(this, Normalizer.Form.NFD).replace("[^\\p{ASCII}]".toRegex(), "")
}

fun String.parseDate(): String {
	return try {
		val sim = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT)
		val data = sim.parse(this)
		DateFormat.getDateInstance(DateFormat.SHORT).format(data!!)
	} catch (ex: Exception) {
		"-/-"
	}
}

fun String.parseDateShot(): String {
	return try {
		val sim = SimpleDateFormat("yyyy-MM-dd", Locale.ROOT)
		val data = sim.parse(this)
		DateFormat.getDateInstance(DateFormat.SHORT).format(data!!)
	} catch (ex: Exception) {
		"-/-"
	}
}

fun String.getDate(format: String = "yyyy-MM-dd"): Date? {
	return try {
		let {
			val sdf = SimpleDateFormat(format, Locale.getDefault())
			sdf.parse(it)
		}
	} catch (e: ParseException) {
		e.printStackTrace()
		null
	}
}

fun String.log(tag: String = "tag"): String {
	Log.d(tag, this)
	return this
}

fun <T> Gson.fromJsonWithLog(json: String?, classOfT: Class<T>): T {
	return this.fromJson<T>(json, classOfT).apply {
		json?.log()
		this.toString().log(classOfT.name)
	}
}

fun String?.notNullOrEmpty() = !this.isNullOrEmpty()

fun String.toPatternName(): CharSequence? {
	return this.toLowerCase().split(" ").reduceRight { s, acc ->
		"${s.capitalize()} ${acc.capitalize()}"
	}
}

/**
 * RECYCLER
 */
fun RecyclerView.patternRecycler(horizont: Boolean = true, divider: Int = 0): RecyclerView {
	layoutManager = LinearLayoutManager(
		context,
		if (horizont) LinearLayoutManager.HORIZONTAL else LinearLayoutManager.VERTICAL,
		false
	)
	if (divider != 0) addCustomDivider(divider)
	itemAnimator = DefaultItemAnimator()
	setHasFixedSize(true)
	return this
}

fun RecyclerView.patternRecyclerGrid(quant: Int = 2): RecyclerView {
	layoutManager = GridLayoutManager(context, quant)
	setHasFixedSize(true)
	itemAnimator = DefaultItemAnimator()
	return this
}

fun RecyclerView.minHeight(): RecyclerView {
	layoutParams.height = 1
	importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
	isFocusable = false
	return this
}

fun RecyclerView.addCustomDivider(divider: Int) {
	DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
		setDrawable(ContextCompat.getDrawable(context, divider)!!)
		addItemDecoration(this)
	}
}

fun RecyclerView.setScrollInvisibleFloatMenu(view: View) {
	addOnScrollListener(object : RecyclerView.OnScrollListener() {
		override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
			when (newState) {
				RecyclerView.SCROLL_STATE_IDLE -> {
					view.visible()
				}
				RecyclerView.SCROLL_STATE_DRAGGING -> {
					view.gone()
				}
				RecyclerView.SCROLL_STATE_SETTLING -> {
					view.gone()
				}
			}
		}
	})
}


/**
 * BottomSheetBehavior
 */
fun BottomSheetBehavior<View>.setAnimation(container: View, viewHeight: View) {
	ValueAnimator.ofInt(container.measuredHeight, viewHeight.marginTop).apply {
		addUpdateListener {
			peekHeight = it.animatedValue as Int
		}
		duration = 500
	}.start()

	container.post {
		val newLayoutParams = (container.layoutParams as? MarginLayoutParams)
		newLayoutParams?.setMargins(0, 0, 0, viewHeight.marginTop + 1)
		container.layoutParams = newLayoutParams
	}
}

/**
 * MutableList
 */
fun <T> MutableList<T>.replaceItemList(item: T, predicate: (T) -> Boolean): MutableList<T> {
	return this.map {
		if (predicate(it)) item else it
	}.toMutableList()
}

/**
 * Array
 */
inline fun <reified T> Array<T>.addHint(filter: T): Array<T> {
	return arrayOf(filter, *this)
}

/**
 * NavigationView
 */
fun <T> NavigationView.findViewOnHeader(id: Int): T? {
	return (getHeaderView(0) as? ViewGroup)
		?.children?.find {
			it.id == id
			// todo por id
		} as? T
}

/**
 * Response - Htttp3
 */
fun Response.contaisErro(json: String?) = json.ifValid { JSONObject(json!!).has("Erro") } ?: false
fun Response.createError(json: String?) =
	if (contaisErro(json)) JSONObject(json!!).getString("Erro") else ""

/**
 * Response - Retrofit
 */
fun <T> retrofit2.Response<T>.contaisErro(json: String?): Boolean =
	json.ifValid { JSONObject(json!!).has("Erro") } ?: false

fun <T> retrofit2.Response<T>.createError(json: String?) =
	if (contaisErro(json)) JSONObject(json!!).getString("Erro") else ""

/**
 * BaseRequest
 */
fun <T> BaseRequest<T>.success() = (this as? Success<T>)?.result
fun <T> BaseRequest<T>.successArray() = (this as? Success<ResponseDiario<Array<T>>>)?.result
fun <T> BaseRequest<ResponseDiario<Array<T>>>.resolverArray(
	activity: Activity,
	successBlock: (data: Array<T>) -> Unit,
	toastSuccess: Boolean = false,
	failure: () -> Unit = {},
	alert: Boolean = true,
	genericError: Boolean = true
) {
	this.resolver(activity, successBlock, toastSuccess, failure, alert, genericError)
}

// val result = (_classes.value as? Success)?.result
// val list = (result as? )?.data ?: arrayOf()
fun <T> BaseRequest<ResponseDiario<T>>.resolver(
	activity: Activity,
	successBlock: (data: T) -> Unit,
	toastSuccess: Boolean = false,
	failure: () -> Unit = {},
	alert: Boolean = true,
	genericError: Boolean = true
) {
	if (alert)
		when (this) {
			is Success -> {
				@Suppress("UNCHECKED_CAST")
				val result = result
				result.let { response ->
					when (response.code) {
						200 -> {
							if (toastSuccess) {
								ToastDiario(activity, result.message ?: "")
									.show(type = SUCCESS)
							}
							successBlock(result.data)
						}
						202 -> ToastDiario(activity, result.message ?: "").show(type = ERRO)
						201, in 203..299 -> ToastDiario(activity,
							result.message ?: "").show(type = ALERT)
					}
				}
			}
			is Failure -> {
				error.toString().log()
				if (genericError) {
					(activity as? BaseActivity)?.error { failure() }
				} else {
					failure()
				}
			}
		}
	else {
		when (this) {
			is Success -> {
				@Suppress("UNCHECKED_CAST")
				val result = result
				result.let { response ->
					if (toastSuccess) ToastDiario(activity,
						response.message ?: "").show(type = SUCCESS)
					successBlock(response.data)
				}
			}
			is Failure -> {
				error.toString().log()
				if (genericError) {
					(activity as? BaseActivity)?.error { failure() }
				} else {
					failure()
				}
			}
		}
	}
}
/**
 * AppCompatSpinner
 */

fun AppCompatSpinner.selectedOneChoose(list: Array<*>) {
	if (list.size == 2) setSelection(list.size - 1)
}
/**
 * Int
 */
fun Int.toDp(context: Context) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
	this.toFloat(), context.resources.displayMetrics).toInt()
/**
 * Float
 */
fun Float.toDp(context: Context) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
	this, context.resources.displayMetrics).toInt()

/**
 * Boolean
 */
fun Boolean.invert() = !this

/**
 * Calendar
 */
fun Calendar.getFormetDateBr(): String {
	return "${this[Calendar.DAY_OF_MONTH]}/${this[Calendar.MONTH]}/${this[Calendar.YEAR]}"
}

fun Calendar.formatApi(): String {
	return time.formatApi()
}

/**
 * Date
 */

fun Date.getFormetDateBr(): String {
	return "${this.day}/${this.month}/${this.year}"
}

fun Date.formatApi(): String {
	// Fri Nov 20 19:15:41 GMT-03:00 2020
	// "MM/dd/yyyy'T'HH:mm:ss"
	// 20/10/2020
	return try {
		return SimpleDateFormat("dd/MM/yyyy").parse(this.getFormetDateBr()).toString()
	} catch (ex: java.lang.Exception) {
		ex.toString()
	}
}

bookmark
dashboard

Sat Nov 21 2020 21:03:31 GMT+0000 (UTC)

#kotlin
bookmark
dashboard

Sat Nov 21 2020 20:59:49 GMT+0000 (UTC)

#kotlin
bookmark
dashboard

Sat Nov 21 2020 20:56:37 GMT+0000 (UTC)

#kotlin

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension