Я пытаюсь отобразить всплывающее окно, которое будет варьироваться между размерами в зависимости от количества строк, которые оно имеет. Другими словами, я пытаюсь создать всплывающую подсказку над видом.
Однако у меня возникают проблемы с постоянным отображением всплывающей подсказки над видом привязки.
Я могу заставить его работать на один размер, используя showAtLocation
, но как только он получит большестрок в тексте, который он охватывает.
Функция showAsDropDown
прекрасно работает! За исключением того, что рисует всплывающую подсказку внизу, а не сверху вид. Я не могу понять, правильно ли я использую гравитацию или что-то в этом роде. Любая помощь здесь, я был бы очень признателен, я как бы застрял здесь.
Вот мой элементарный код на данный момент:
@SuppressWarnings("unused")
class SimpleTooltip : PopupWindow() {
companion object {
const val TAG = "SimpleTooltip"
}
private var popupWindow: PopupWindow? = null //The popup window the will be created in the builder.
private var popupView: View? = null //The popup view that will inflate the popup window.
private var focusable: Boolean? = false //dismiss PopupWindow when touch outside AND when press back button
private var outsideTouchable: Boolean? = true // dismiss PopupWindow when touch outside
private var drawable: Drawable? = null //The background drawable of the popup window. This is still visible even if we have a layout defined.
private var anchorView: View? = null //The view to anchor the popup window to.
private var gravity: Int? = null //The gravity of the popup -> where should it be displayed? Top, bottom?
private var layout: Int? = null //The layout of the popup.
private var xPosition: Int? = null //Move the view X amount horizontally.
private var yPosition: Int? = null //Move the view Y amount vertically.
private var message: String? = null //The message to be displayed.
private var parentViewGroup: ViewGroup? = null // the parent view
private var context: Context? = null //The context..duh
fun withFocusableEnabled(isFocusable: Boolean) = apply { this.focusable = isFocusable }
fun withTouchOutsideEnabled(isOutsideTouchable: Boolean) = apply { this.isOutsideTouchable = isOutsideTouchable }
fun withContext(context: Context) = apply { this.context = context }
fun withLayout(layout: Int) = apply { this.layout = layout }
fun withAnchorView(anchorView: View) = apply { this.anchorView = anchorView }
fun withGravity(gravity: Int) = apply { this.gravity = gravity }
fun withOnDismissAction(action: () -> Unit) = apply { this.setOnDismissListener { action.invoke() } }
fun withMessage(message: String) = apply { this.message = message }
fun withBackgroundDrawable(drawable: Drawable?) = apply { this.drawable= drawable }
fun withXPosition(paddingX: Int) = apply { this.xPosition = paddingX }
fun withYPosition(paddingY: Int) = apply { this.yPosition = paddingY }
fun withParentView(parentViewGroup: ViewGroup) = apply { this.parentViewGroup = parentViewGroup }
fun build() = apply {
Log.v(TAG, "Attempting to build the tooltip")
if (context == null) throw InvalidContextProvidedException("No context provided to inflate the view. Please provide one.")
if (layout == null) throw InvalidLayoutException("No layout provided to inflate the view. Please provide one.")
layout?.let { layout ->
popupView = (context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(layout, parentViewGroup)
popupWindow = PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
focusable?.let { this.isFocusable = it }
outsideTouchable?.let { this.isOutsideTouchable = it }
drawable?.let { this.setBackgroundDrawable(it) }
message?.let {
val textView: TextView = popupView?.find(R.id.tooltip_layout_text_view)
?: throw InvalidTextViewId("Please name the text view on your layout as \'tooltip_layout_text_view\'")
textView.text = message
}
}
}
fun showPopup() {
Log.v(TAG, "Attempting to show popup.")
if (anchorView == null) throw InvalidAnchorViewException("No anchor view provided to place the popup window on. Please provide one.")
if (popupView == null || popupWindow == null) throw InvalidStateException("The tooltip was not built. Please call the build() method.")
gravity?.let {
popupWindow?.showAsDropDown(anchorView, xPosition ?: 0, yPosition ?: 0, it)
} ?: popupWindow?.showAsDropDown(anchorView, xPosition ?: 0, yPosition ?: 0)
}
fun dismissPopup() {
popupWindow?.apply {
if (isShowing) dismiss()
}
}
}
class InvalidAnchorViewException(message: String) : Exception(message)
class InvalidContextProvidedException(message: String) : Exception(message)
class InvalidTextViewId(message: String) : Exception(message)
class InvalidLayoutException(message: String) : Exception(message)
class InvalidStateException(message: String) : Exception(message)
И вот как я это называю:
tooltip = SimpleTooltip()
.withContext(this)
.withLayout(R.layout.tooltip_layout)
.withAnchorView(anchorView)
.withFocusableEnabled(true)
.withTouchOutsideEnabled(false)
.withMessage(getPopupMessageFromDate(expiryDate))
.withBackgroundDrawable(ColorDrawable())
.build()
.showPopup()