Skip to content

Commit

Permalink
Code review-2 [#25] P3, P4, P5, P6 - MaterialBanner fixes, saving fla…
Browse files Browse the repository at this point in the history
…g in bundle for location check
  • Loading branch information
E-D-W-I-N committed May 18, 2021
1 parent f7fc2ef commit 4469745
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,40 @@ class MaterialBanner @JvmOverloads constructor(
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

private var _contentText: String? = null
private var _leftButtonText: String? = null
private var _rightButtonText: String? = null
private var _iconDrawableRes: Drawable? = null
private var binding: MaterialBannerBinding

var contentText: String?
get() = _contentText
private val binding: MaterialBannerBinding

var contentText: String? = null
set(value) {
_contentText = value
field = value
binding.contentTextView.text = value
}

var leftButtonText: String?
get() = _leftButtonText
var leftButtonText: String? = null
set(value) {
_leftButtonText = value
field = value
binding.leftButton.text = value
}

var rightButtonText: String?
get() = _rightButtonText
var rightButtonText: String? = null
set(value) {
_rightButtonText = value
field = value
binding.rightButton.text = value
}

var iconDrawableRes: Drawable?
get() = _iconDrawableRes
var iconDrawableRes: Drawable? = null
set(value) {
_iconDrawableRes = value
field = value
binding.contentIconView.setImageDrawable(value)
binding.contentIconView.visibility = View.VISIBLE
}

init {
val view = inflate(context, R.layout.material_banner, this)
binding = MaterialBannerBinding.bind(view)
takeValuesFromAttr(attrs, view)
}

private fun takeValuesFromAttr(attrs: AttributeSet?, view: View) = with(binding) {
val typedArray = context.obtainStyledAttributes(
attrs, R.styleable.MaterialBanner, 0, 0
)
Expand All @@ -80,27 +75,28 @@ class MaterialBanner @JvmOverloads constructor(
R.styleable.MaterialBanner_icon
)

binding.bannerLayout.setBackgroundColor(
bannerLayout.setBackgroundColor(
typedArray.getColor(
R.styleable.MaterialBanner_bannerBackgroundColor,
MaterialColors.getColor(view, R.attr.colorPrimary)
)
)

binding.contentTextView.setTextColor(
contentTextView.setTextColor(
typedArray.getColor(
R.styleable.MaterialBanner_contentTextColor,
ContextCompat.getColor(context, R.color.blue)
)
)

binding.leftButton.setTextColor(
leftButton.setTextColor(
typedArray.getColor(
R.styleable.MaterialBanner_buttonsTextColor,
ContextCompat.getColor(context, R.color.blue)
)
)
binding.rightButton.setTextColor(

rightButton.setTextColor(
typedArray.getColor(
R.styleable.MaterialBanner_buttonsTextColor,
ContextCompat.getColor(context, R.color.blue)
Expand All @@ -110,7 +106,6 @@ class MaterialBanner @JvmOverloads constructor(
typedArray.recycle()
}


fun showBanner(
@StringRes message: Int?,
@DrawableRes icon: Int?,
Expand All @@ -123,12 +118,11 @@ class MaterialBanner @JvmOverloads constructor(
iconDrawableRes = icon?.let { ContextCompat.getDrawable(context, it) }
leftButtonText = leftBtnText?.let { context.getString(it) }
rightButtonText = rightBtnText?.let { context.getString(it) }
this.setLeftButtonAction { leftButtonAction() }
this.setRightButtonAction { rightButtonAction() }
this.expand()
}
setLeftButtonAction { leftButtonAction() }
setRightButtonAction { rightButtonAction() }
show()

fun dismiss() = this.collapse()
}

fun setLeftButtonAction(action: () -> Unit) = binding.leftButton.setOnClickListener {
action()
Expand All @@ -138,53 +132,50 @@ class MaterialBanner @JvmOverloads constructor(
action()
}

private fun View.expand() {
this@expand.measure(
fun show() {
measure(
LayoutParams.MATCH_CONSTRAINT,
LayoutParams.WRAP_CONTENT
)
val targetHeight = this@expand.measuredHeight
val targetHeight = measuredHeight

this@expand.layoutParams.height = 0
this@expand.visibility = View.VISIBLE
layoutParams.height = 0
visibility = View.VISIBLE
val animation = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
this@expand.layoutParams.height = if (interpolatedTime == 1f)
layoutParams.height = if (interpolatedTime == 1f)
ViewGroup.LayoutParams.WRAP_CONTENT
else
(targetHeight * interpolatedTime).toInt()
this@expand.requestLayout()
requestLayout()
}

override fun willChangeBounds(): Boolean = true
}

animation.duration =
(targetHeight / this@expand.context.resources.displayMetrics.density).toInt().toLong()
this@expand.startAnimation(animation)
(targetHeight / context.resources.displayMetrics.density).toInt().toLong()
startAnimation(animation)
}

private fun View.collapse() {
val initialHeight = this.measuredHeight

fun dismiss() {
val initialHeight = measuredHeight
val animation = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
if (interpolatedTime == 1f) {
this@collapse.visibility = View.GONE
visibility = View.GONE
} else {
this@collapse.layoutParams.height =
initialHeight - (initialHeight * interpolatedTime).toInt()
this@collapse.requestLayout()
layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
requestLayout()
}
}

override fun willChangeBounds(): Boolean = true
}

animation.duration =
(initialHeight / this.context.resources.displayMetrics.density).toInt().toLong()
this.startAnimation(animation)
(initialHeight / context.resources.displayMetrics.density).toInt().toLong()
startAnimation(animation)
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ class MapFragment : Fragment(R.layout.map_fragment), OnMapReadyCallback {
private val viewModel: MapViewModel by viewModel()
private val binding by viewBinding(MapFragmentBinding::bind)
private lateinit var map: GoogleMap
private var isLocationNotChecked = true

companion object {
private const val LOCATION_PERMISSION = Manifest.permission.ACCESS_COARSE_LOCATION
private const val MAP_ZOOM = 8F
private const val IS_LOCATION_NOT_CHECKED = "isLocationNotChecked"
}

private val requestPermissionLauncher = registerForActivityResult(
Expand All @@ -47,6 +49,10 @@ class MapFragment : Fragment(R.layout.map_fragment), OnMapReadyCallback {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
savedInstanceState?.let {
isLocationNotChecked = it.getBoolean(IS_LOCATION_NOT_CHECKED)
}

binding.apply {
mapView.onCreate(savedInstanceState)
mapView.getMapAsync(this@MapFragment)
Expand Down Expand Up @@ -86,12 +92,14 @@ class MapFragment : Fragment(R.layout.map_fragment), OnMapReadyCallback {
)
is MapException.NoLastLocation -> {
binding.banner.showBanner(
R.string.current_location_error_text,
R.drawable.ic_location_off,
R.string.action_dismiss,
R.string.action_retry,
{ binding.banner.dismiss() },
{ binding.banner.dismiss().also { viewModel.getFusedLocation() } }
message = R.string.current_location_error_text,
icon = R.drawable.ic_location_off,
leftBtnText = R.string.action_dismiss,
rightBtnText = R.string.action_retry,
leftButtonAction = { binding.banner.dismiss() },
rightButtonAction = {
binding.banner.dismiss().also { viewModel.getFusedLocation() }
}
)
}
}
Expand All @@ -103,9 +111,9 @@ class MapFragment : Fragment(R.layout.map_fragment), OnMapReadyCallback {
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
setupObservers()
if (viewModel.isLocationNotChecked) {
if (isLocationNotChecked) {
checkPermissions()
viewModel.isLocationNotChecked = false
isLocationNotChecked = false
}
map.setOnMapClickListener { latLng ->
moveCameraToLocation(latLng)
Expand Down Expand Up @@ -182,6 +190,11 @@ class MapFragment : Fragment(R.layout.map_fragment), OnMapReadyCallback {
}
}

override fun onSaveInstanceState(outState: Bundle) {
outState.putBoolean(IS_LOCATION_NOT_CHECKED, isLocationNotChecked)
super.onSaveInstanceState(outState)
}

override fun onStart() {
super.onStart()
binding.mapView.onStart()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ class MapViewModel(
private val eventChannel = Channel<ActionState>(Channel.BUFFERED)
val eventsFlow = eventChannel.receiveAsFlow()

var isLocationNotChecked: Boolean = true

fun getFusedLocation() = viewModelScope.launch {
_uiState.value = MapUiState.Loading
val location = getFusedLocationUseCase(Unit).single()
Expand Down
1 change: 0 additions & 1 deletion app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
<color name="white">#FFFFFFFF</color>
<color name="blue">#4A90E2</color>
<color name="gray_B2B">#B2B2B2</color>
<color name="gray_666">#666666</color>
<color name="gray_353">#353535</color>
</resources>

0 comments on commit 4469745

Please sign in to comment.