I know there are a lot of 3rd party libraries on <...
# android
l
I know there are a lot of 3rd party libraries on android-arsenal.com for tooltips, but if i wanted to create my own custom View, how should I go about this? I want to avoid having to draw to the Canvas to create the tooltip. At the moment I have the content in one view and the arrow in another view. I want to position the arrow either on top or on bottom of the content, and i want to position it a percentage distance from the left or right. I was thinking of using ConstraintLayouts and horizontal biases. Am i on the right track?
😶 2
Here are some of my requirements Tooltip - position : tooltip position relative to anchorView - anchorView : the view that the tooltip will be anchored/aligned to - backgroundColor - arrowPosition - cornerRadius - arrow - content view - margins / padding - clicklistener for child view in content view
b
PopupWindow
we did the same thing at PLANOLY
Screenshot_20210715-151603.png
the content of it can be a simple constraintlayout and can control shape, color of the content view (and click listener) like:
Copy code
fun generateTipContent(
    context: Context,
    themeAttrs: TooltipPopupWindow.ThemeAttributes,
    styler: TooltipPopupWindow.Styler,
    onClick: () -> Unit,
): ConstraintLayout {
    val card = View.inflate(context, R.layout.tooltip_content, null) as ConstraintLayout
    return card.apply {
        layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )

        updateBackground(themeAttrs.popupElevation)
        MaterialShapeUtils.setParentAbsoluteElevation(this)
        // clipping to outline on <= API 28 prevents the edge treatment to apply
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            clipToOutline = true
        }
    }.also { contentView ->
        contentView.findViewById<MaterialTextView>(R.id.tooltip_message).text = styler.message
        val hasUpsell = styler.ctaLabel != null && styler.ctaOnClick != null
        contentView.findViewById<MaterialButton>(R.id.tooltip_cta).apply {
            isVisible = hasUpsell
            if (hasUpsell) {
                text = styler.ctaLabel
                paintFlags = paintFlags or Paint.UNDERLINE_TEXT_FLAG
                setOnClickListener { onClick() }
            }
        }
    }
}
arrow position is calculated based on target gravity relative to the anchor and is offset based on tip popupwindow center
l
so can you customize the look of the arrow?
Screen Shot 2021-07-15 at 12.49.33 PM.png
i want the arrow to be rounded
i also can't have the drop shadow
b
the arrow is part of the shape drawable
Copy code
fun generateTriangleEdge(
    offset: Float,
    size: Float = 10.px.toFloat(),
    inside: Boolean = false,
): TriangleEdgeTreatment {

    return object : TriangleEdgeTreatment(size, inside) {
        override fun getEdgePath(
            length: Float,
            center: Float,
            interpolation: Float,
            shapePath: ShapePath
        ) {
            val offsetCenter = (center + offset)
            shapePath.lineTo(offsetCenter - size * interpolation, 0f)
            shapePath.lineTo(
                offsetCenter,
                if (inside) size * interpolation else -size * interpolation
            )
            shapePath.lineTo(offsetCenter + size * interpolation, 0f)
            shapePath.lineTo(length, 0f)
        }
    }
}
l
do you have an open source repo for this?
it looks like you have to draw to the canvas for your implementation
i was trying to come up with a solution that didnt need to draw to the canvas
b
lemme see if I can get it up in a gist
(or a repo)