Skip to content

Instantly share code, notes, and snippets.

@fiskurgit
Last active March 13, 2019 10:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fiskurgit/b39bc3d0b016e2a81dc10c741a2ce80c to your computer and use it in GitHub Desktop.
Save fiskurgit/b39bc3d0b016e2a81dc10c741a2ce80c to your computer and use it in GitHub Desktop.
import android.app.Activity
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.Point
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.support.design.widget.BottomSheetBehavior
import android.support.design.widget.CoordinatorLayout
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
class FiskDialog(context: Activity, layout: Int, theme: Int) {
val dialog: Dialog
val contentView: View
private var cancelable = true
val coordinatorLayout: CoordinatorLayout
init {
dialog = Dialog(context, theme)
val window = dialog.window
if (window != null) {
window.setDimAmount(0f)
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}
contentView = context.layoutInflater.inflate(layout, null)
//Curved top corners:
val curvedBackground = GradientDrawable()
curvedBackground.setColor(Color.WHITE)
val cornerRadius = 8 * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
curvedBackground.cornerRadii = floatArrayOf(cornerRadius, cornerRadius, cornerRadius, cornerRadius, 0f, 0f, 0f, 0f)
contentView.background = curvedBackground
//Full screen coordinator to hold the bottomsheet
coordinatorLayout = CoordinatorLayout(context)
val layoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)
layoutParams.gravity = Gravity.CENTER
coordinatorLayout.layoutParams = layoutParams
coordinatorLayout.setBackgroundColor(Color.parseColor("#00000000"))
val bottomSheetBehavior = BottomSheetBehavior<View>()
bottomSheetBehavior.skipCollapsed = true
bottomSheetBehavior.isHideable = true
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
val params = CoordinatorLayout.LayoutParams(CoordinatorLayout.LayoutParams.MATCH_PARENT, CoordinatorLayout.LayoutParams.WRAP_CONTENT)
params.behavior = bottomSheetBehavior
contentView.layoutParams = params
coordinatorLayout.addView(contentView)
//Any click on the dimmed coordinator in the background should dismiss the dialog (unless setCanceleable(false); has been called):
coordinatorLayout.setOnClickListener { _view -> if (cancelable) BottomSheetBehavior.from(contentView).state = BottomSheetBehavior.STATE_HIDDEN }
bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
when (newState) {
BottomSheetBehavior.STATE_HIDDEN -> {
dialog.dismiss()
//todo - create dismiss listener interface
}
}
}
//slideOffset is float in range 0 to 1 - remapped to 0 to 153 (0x99000000)
override fun onSlide(bottomSheet: View, slideOffset: Float) {
val alpha = map(slideOffset, 0f, 1f, 0f, 153f).toInt()
val overlayColor = Color.argb(alpha, Color.red(Color.BLACK), Color.green(Color.BLACK), Color.blue(Color.BLACK))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && window != null) {
window.statusBarColor = overlayColor
}
coordinatorLayout.setBackgroundColor(overlayColor)
}
})
dialog.setContentView(coordinatorLayout)
//Without this the bottom sheet doesn't animate, despite the default state being hidden
BottomSheetBehavior.from(contentView).state = BottomSheetBehavior.STATE_HIDDEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) dialog.create()
}
fun show() {
dialog.show()
contentView.post { BottomSheetBehavior.from(contentView).setState(BottomSheetBehavior.STATE_EXPANDED) }
}
fun dismiss() {
BottomSheetBehavior.from(contentView).state = BottomSheetBehavior.STATE_HIDDEN
}
fun setOnShowListener(onShowListener: DialogInterface.OnShowListener) {
dialog.setOnShowListener(onShowListener)
}
fun setCancelable(cancelable: Boolean) {
this.cancelable = cancelable
dialog.setCancelable(cancelable)
}
private fun map(value: Float, start1: Float, stop1: Float, start2: Float, stop2: Float): Float {
return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1))
}
fun setMaxWidth(dp: Float) {
val maxWidth = Math.round(contentView.context.resources.displayMetrics.density * dp)
val display = dialog.window!!.windowManager.defaultDisplay
val size = Point()
display.getSize(size)
if (size.x > maxWidth) {
contentView.layoutParams.width = maxWidth
(contentView.layoutParams as CoordinatorLayout.LayoutParams).gravity = Gravity.CENTER_HORIZONTAL
}
}
fun setMaxWidth(dimenRes: Int) {
val dp = contentView.context.resources.getDimension(dimenRes)
setMaxWidth(dp)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment