Last active
March 13, 2019 10:09
-
-
Save fiskurgit/b39bc3d0b016e2a81dc10c741a2ce80c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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