Open jlucas577 opened 3 years ago
@jlucas577 First of all you need to fix your layout on a small screens. Second you need to redesign overlay view, and put title and description of your tutorial at the very top. Or when ui component is at the top of the screen you need to readjust title and description to the bottom. Check example from my app:
private fun initOverlayView(
rootView: View,
targetView: View,
activity: RootActivity,
) {
val overlay: View = activity.layoutInflater
.inflate(R.layout.block_tutorial_feature, rootView, false)
val targetWidth: Float = targetView.width.toFloat()
val targetHeight: Float = targetView.height.toFloat()
val targetMinSize: Float = min(targetWidth, targetHeight)
val targetMaxSize: Float = max(targetWidth, targetHeight)
val location = IntArray(2)
targetView.getLocationInWindow(location)
// This is coords on window. It is hard to say where is start point.
// But it seems that in split screen mode without status bar,
// but without split screen mode it includes status bar
val targetLeft: Float = location[0].toFloat()
val targetTop: Float = location[1].toFloat()
val targetRight: Float = targetLeft + targetView.width
val targetBottom: Float = targetTop + targetView.height
val targetCenterX: Float = targetLeft + targetWidth * 0.5f
val targetCenterY: Float = targetTop + targetHeight * 0.5f
val horizontalPadding: Int = activity.calcTutTextHorizPadding(rootView)
val isInMultiWindowMode: Boolean =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) activity.isInMultiWindowMode else false
overlay.findViewById<View>(R.id.tutorial_container).let {
it.setOnTouchListener { v, event ->
val eventX = if (isInMultiWindowMode) event.x else event.rawX
val eventY = if (isInMultiWindowMode) event.y else event.rawY
if (eventX in targetLeft..targetRight
&& eventY in targetTop..targetBottom
&& isTargetClickable
) {
false // Pass event under the hole
} else {
true // Consume event
}
}
}
val titleField = overlay.findViewById<TextView>(R.id.tutorial_title_field).also {
it.updatePadding(left = horizontalPadding, right = horizontalPadding)
if (title.isNullOrEmpty()) {
it.visibility = View.GONE
} else {
it.text = title
}
}
val descriptionField = overlay.findViewById<TextView>(R.id.tutorial_description_field).also {
it.updatePadding(left = horizontalPadding, right = horizontalPadding)
if (description.isNullOrEmpty()) {
it.visibility = View.GONE
} else {
it.text = description
}
}
val okButton = overlay.findViewById<MaterialButton>(R.id.tutorial_ok_button).also {
if (hasOk) {
it.setOnClickListener {
finish(activity)
}
} else {
it.visibility = View.GONE
}
}
overlay.findViewById<View>(R.id.tutorial_try_button).visibility = View.GONE
overlay.findViewById<ViewGroup>(R.id.tutorial_content_container).let { container ->
if (isContentTransparent) {
container.setBackgroundColor(ColorsAcore.transparent)
}
titleField.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
descriptionField.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
iconView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
container.updateLayoutParams<RelativeLayout.LayoutParams> {
// Status bar as margin between hole and content
val contentMargin: Int = activity.getDimensionPixelSize(R.dimen.tutorial_content_vert_margin)
// In multiwindow mode status bar not counted as window size
val statusBarHeight: Int = if (isInMultiWindowMode) 0 else activity.statusBarHeight
val contentHeight = titleField.measuredHeight + descriptionField.measuredHeight +
iconView.measuredHeight + contentMargin
val windowHeight: Int = activity.windowHeightNoSysBars
val topRestHeight: Float = targetTop - statusBarHeight
val bottomRestHeight: Float = windowHeight - targetBottom
when {
// If top and bottom rest smaller than content
topRestHeight < contentHeight
&& bottomRestHeight < contentHeight -> {
if (!isContentTransparent) {
container.setBackgroundColor(ColorsApp.tutorialBgColor)
}
adjustOkButtonColor(okButton, targetBottom)
}
// Top rest much bigger than bottom one. Show content above hole
topRestHeight > bottomRestHeight * 1.3f -> {
this.bottomMargin = windowHeight - (targetTop.toInt() - statusBarHeight) + contentMargin
adjustOkButtonColor(okButton, targetBottom)
}
// Default, show content below the hole
else -> {
this.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE)
this.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
// It is safe to set targetBottom as a topMargin, so there should be an extra margin
// between hole and top edge of the content which equals to notification bar height
this.topMargin = targetBottom.toInt() - statusBarHeight + contentMargin
this.bottomMargin = 0 // Or it will hide part of big content block
}
}
}
}
}
@jlucas577 Also when you have components inside ScrollView which you want to highlight. First you need to scroll ScrollView to ensure targetView is visible on a small screen.
Hello guys! I opened this pr to get help on a possible responsiveness of the library, my problem is that when I position the view on a particular float, on larger screens it is excellent and working very well, however on smaller screens it just stops being "responsive" and the view ends up being on top of others that it shouldn't ..
I've tried to set the screen percentage as a top margin for example, but the problem still persists, and the funniest thing is that it only happens on screens smaller than 5 inches.