Commit a60ca88a authored by 王韦's avatar 王韦

[new] tip 初步完成

parent 00646619
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name=".CommomPopActivity"></activity> <activity android:name=".TipActivity"></activity>
<activity android:name=".CommomPopActivity" />
<activity android:name=".TopBarActivity" /> <activity android:name=".TopBarActivity" />
<activity android:name=".MainActivity"> <activity android:name=".MainActivity">
<intent-filter> <intent-filter>
......
package com.qimai.android.widget;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.qimai.android.widgetlib.popup.QmAlertDialog;
import kotlin.jvm.functions.Function1;
/**
* created by wangwei ON 2019-08-28 email:wangwei_5521@163.com
*
* @version 1.1.1
* @Description
**/
public class AlertDialogActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
...@@ -18,5 +18,10 @@ class MainActivity : AppCompatActivity() { ...@@ -18,5 +18,10 @@ class MainActivity : AppCompatActivity() {
startActivity(Intent(MainActivity@ this, CommomPopActivity::class.java)) startActivity(Intent(MainActivity@ this, CommomPopActivity::class.java))
} }
findViewById<Button>(R.id.tip).setOnClickListener {
startActivity(Intent(MainActivity@ this, TipActivity::class.java))
}
} }
} }
package com.qimai.android.widget
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.qimai.android.widgetlib.popup.QmToolTip
class TipActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_tip)
findViewById<Button>(R.id.top).setOnClickListener {
val view = LayoutInflater.from(TipActivity@ this).inflate(R.layout.tip, null)
QmToolTip.Builder()
.withAttachedView(findViewById(R.id.top))
.withContentView(view)
.withGravity(Gravity.TOP)
.build().show()
}
findViewById<Button>(R.id.bottom).setOnClickListener {
val view = LayoutInflater.from(TipActivity@ this).inflate(R.layout.tip, null)
QmToolTip.Builder()
.withAttachedView(findViewById<Button>(R.id.bottom))
.withContentView(view)
.withGravity(Gravity.BOTTOM)
.build().show()
}
}
}
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="50dp" /> android:layout_height="50dp" />
<Button
android:id="@+id/tip"
android:text="Tip"
android:layout_width="match_parent"
android:layout_height="50dp" />
</LinearLayout> </LinearLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TipActivity">
<Button
android:id="@+id/top"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginTop="140dp"
android:text="top"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/bottom"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginTop="140dp"
android:text="bottom"
app:layout_constraintEnd_toStartOf="@+id/top"
app:layout_constraintHorizontal_bias="0.144"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试测试测试\n 测试测试测试"
android:textColor="#C02F14"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试测试测试\n 测试测试测试"
android:textColor="#C02F14"
android:textSize="10sp" />
</LinearLayout>
\ No newline at end of file
...@@ -2,6 +2,7 @@ package com.qimai.android.tools ...@@ -2,6 +2,7 @@ package com.qimai.android.tools
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import androidx.core.content.edit
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
/** /**
...@@ -41,27 +42,37 @@ class SharedPreferencesTools { ...@@ -41,27 +42,37 @@ class SharedPreferencesTools {
fun putString(key: String, value: String) { fun putString(key: String, value: String) {
check() check()
sp!!.edit().putString(key, value).apply() sp?.edit {
putString(key, value)
}
} }
fun putInt(key: String, value: Int) { fun putInt(key: String, value: Int) {
check() check()
sp!!.edit().putInt(key, value).apply() sp?.edit {
putInt(key, value).apply()
}
} }
fun putBoolean(key: String, value: Boolean) { fun putBoolean(key: String, value: Boolean) {
check() check()
sp!!.edit().putBoolean(key, value).apply() sp?.edit {
putBoolean(key, value)
}
} }
fun remove(key: String) { fun remove(key: String) {
check() check()
sp!!.edit().remove(key).apply() sp?.edit {
remove(key)
}
} }
fun clear() { fun clear() {
check() check()
sp!!.edit().clear().apply() sp?.edit {
clear()
}
} }
private fun check() { private fun check() {
......
package com.qimai.android.widgetlib package com.qimai.android.widgetlib
import android.graphics.Canvas import android.graphics.*
import android.graphics.ColorFilter
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.util.Log import android.os.Build
/** /**
* created by wangwei ON 2019-08-29 email:wangwei_5521@163.com * created by wangwei ON 2019-08-29 email:wangwei_5521@163.com
...@@ -13,7 +10,33 @@ import android.util.Log ...@@ -13,7 +10,33 @@ import android.util.Log
* @Description * @Description
**/ **/
class TestDrawable : Drawable() { class TestDrawable : Drawable() {
val rectF: RectF
val arrowHeight = 20.0f
var arrowPath = Path()
var path = Path()
val radius = 10.0f
var borderPaint = Paint()
val outlineRect= Rect()
init {
borderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
borderPaint.style = Paint.Style.STROKE
borderPaint.strokeJoin = Paint.Join.ROUND
borderPaint.strokeWidth = 2.0f
borderPaint.color = Color.BLACK
path = Path()
arrowPath = Path()
rectF = RectF()
}
override fun draw(canvas: Canvas) { override fun draw(canvas: Canvas) {
borderPaint?.let {
canvas.drawPath(arrowPath, it)
}
borderPaint?.let {
canvas.drawPath(path, it)
}
} }
override fun setAlpha(alpha: Int) { override fun setAlpha(alpha: Int) {
...@@ -24,12 +47,38 @@ class TestDrawable : Drawable() { ...@@ -24,12 +47,38 @@ class TestDrawable : Drawable() {
} }
override fun getOutline(outline: Outline) {
super.getOutline(outline)
copyBounds(outlineRect)
outlineRect.inset(10, 10)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
outline.setRoundRect(outlineRect, radius)
} else {
// 5.0以下
}
}
override fun setColorFilter(colorFilter: ColorFilter?) { override fun setColorFilter(colorFilter: ColorFilter?) {
} }
override fun onBoundsChange(bounds: Rect?) { override fun onBoundsChange(bounds: Rect?) {
super.onBoundsChange(bounds) super.onBoundsChange(bounds)
Log.v("drawableT", "${bounds!!.right},${bounds!!.bottom}")
val left = bounds!!.left
val right = bounds!!.right
var top = bounds?.top
var bottom = bounds.bottom
rectF.set(left.toFloat() + arrowHeight+20, top.toFloat()+10, right.toFloat(), bottom.toFloat())
path.addRoundRect(rectF, radius, radius, Path.Direction.CW)
val radioHeight = (bottom - top) * 0.5f
arrowPath.moveTo(left + arrowHeight+20, top + radioHeight + arrowHeight)
arrowPath.lineTo(left.toFloat()+20, top + radioHeight)
arrowPath.lineTo(left + arrowHeight+20, top + radioHeight - arrowHeight)
arrowPath.close()
} }
} }
\ No newline at end of file
package com.qimai.android.widgetlib.popup package com.qimai.android.widgetlib.popup
import android.content.Context
import android.graphics.* import android.graphics.*
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.view.Gravity
import com.qimai.android.tools.dpTopx
import com.qimai.android.widgetlib.R import com.qimai.android.widgetlib.R
/** /**
...@@ -11,22 +12,23 @@ import com.qimai.android.widgetlib.R ...@@ -11,22 +12,23 @@ import com.qimai.android.widgetlib.R
* @version 1.1.1 * @version 1.1.1
* @Description * @Description
**/ **/
internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder) : Drawable() { internal class QmTipOverlayDrawable(builder: QmToolTip.Builder) : Drawable() {
private val outlineRect = Rect() private val outlineRect = Rect()
private val radius: Float private val radius: Float
private val bgColor: Int private val bgColor: Int
private val borderWidth: Int private var borderWidth: Int
private val borderColor: Int private var borderColor: Int
private val bgPaint: Paint? private val bgPaint: Paint?
private val borderPaint: Paint? private val borderPaint: Paint?
private val path: Path private val path: Path
private val arrowPath: Path
private var padding = 0 private var padding = 0
private var gravity = 0 private var gravity = builder.gravity
private var showArrow = true
private val rectF: RectF private val rectF: RectF
private val arrowHeight = 20f
/** /**
* 0-1 * 0-1
...@@ -34,6 +36,7 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder ...@@ -34,6 +36,7 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder
private var arrowWeight = 0.5f private var arrowWeight = 0.5f
init { init {
val context = builder.contentView!!.context
val theme = context.theme.obtainStyledAttributes( val theme = context.theme.obtainStyledAttributes(
null, null,
R.styleable.QmToolTipOverlay, R.styleable.QmToolTipOverlay,
...@@ -41,13 +44,19 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder ...@@ -41,13 +44,19 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder
0 0
) )
this.radius = this.radius =
theme.getDimensionPixelSize(R.styleable.QmToolTipOverlay_overlay_radius, 4).toFloat() theme.getDimensionPixelSize(
R.styleable.QmToolTipOverlay_overlay_radius,
context.dpTopx(5f)
).toFloat()
this.bgColor = theme.getColor( this.bgColor = theme.getColor(
R.styleable.QmToolTipOverlay_overlay_bgColor, R.styleable.QmToolTipOverlay_overlay_bgColor,
context.resources.getColor(R.color.QmTopBar_color_FFFFFFF) context.resources.getColor(R.color.QmTopBar_color_FFFFFFF)
) )
this.borderWidth = this.borderWidth =
theme.getDimensionPixelOffset(R.styleable.QmToolTipOverlay_overlay_borderWidth, 1) theme.getDimensionPixelOffset(
R.styleable.QmToolTipOverlay_overlay_borderWidth,
context.dpTopx(1f)
)
this.borderColor = theme.getColor( this.borderColor = theme.getColor(
R.styleable.QmToolTipOverlay_overlay_borderColor, R.styleable.QmToolTipOverlay_overlay_borderColor,
context.resources.getColor(R.color.QmTopBar_color_FFFFFFF) context.resources.getColor(R.color.QmTopBar_color_FFFFFFF)
...@@ -62,22 +71,28 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder ...@@ -62,22 +71,28 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder
borderPaint = Paint(Paint.ANTI_ALIAS_FLAG) borderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
bgPaint.color = borderColor bgPaint.color = borderColor
borderPaint.style = Paint.Style.STROKE borderPaint.style = Paint.Style.STROKE
borderPaint.strokeJoin = Paint.Join.ROUND
borderPaint.strokeWidth = borderWidth.toFloat() borderPaint.strokeWidth = borderWidth.toFloat()
} else { } else {
borderPaint = null borderPaint = null
} }
path = Path() path = Path()
arrowPath = Path()
} }
override fun draw(canvas: Canvas) { override fun draw(canvas: Canvas) {
bgPaint?.let { path.op(arrowPath, Path.Op.XOR)
canvas.drawPath(path, it)
}
borderPaint?.let { borderPaint?.let {
canvas.drawPath(path, it) canvas.drawPath(path, it)
} }
// borderPaint?.let {
// canvas.drawPath(arrowPath,it)
// }
// borderPaint?.let {
// canvas.drawPath(path, it)
// }
} }
...@@ -125,7 +140,7 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder ...@@ -125,7 +140,7 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder
val minY = top + radius val minY = top + radius
val minX = left + radius val minX = left + radius
if (showArrow) { if (gravity != Gravity.NO_GRAVITY) {
calculatePathWithGravity( calculatePathWithGravity(
outBounds = outBounds, outBounds = outBounds,
left = left, left = left,
...@@ -157,14 +172,135 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder ...@@ -157,14 +172,135 @@ internal class QmTipOverlayDrawable(context: Context, builder: QmToolTip.Builder
minX: Float minX: Float
) { ) {
when (gravity) {
Gravity.TOP -> {
drawArrowTopWithRect(left, top, right, bottom)
}
Gravity.BOTTOM -> {
drawArrowBottomWithRect(left, top, right, bottom)
}
}
}
/**
* 箭头朝上
*/
private fun drawArrowTopWithRect(
left: Int,
top: Int,
right: Int,
bottom: Int
) {
rectF.set(
left.toFloat() + borderWidth,
top.toFloat() + borderWidth,
right.toFloat() - borderWidth,
bottom.toFloat() - arrowHeight-borderWidth
)
path.addRoundRect(rectF, radius, radius, Path.Direction.CW)
val radioHeight = (right - left) * arrowWeight
arrowPath.moveTo(left + radioHeight+borderWidth -arrowHeight, bottom - arrowHeight-borderWidth)
arrowPath.lineTo(
left.toFloat() + radioHeight+borderWidth,
(bottom - borderWidth).toFloat()
)
arrowPath.lineTo(left + radioHeight + arrowHeight+borderWidth, bottom - arrowHeight-borderWidth)
arrowPath.close()
}
private fun drawArrowBottomWithRect(
left: Int,
top: Int,
right: Int,
bottom: Int
) {
rectF.set(
left.toFloat() + borderWidth,
top.toFloat() + borderWidth + arrowHeight,
right.toFloat() - borderWidth,
bottom.toFloat() - borderWidth
)
path.addRoundRect(rectF, radius, radius, Path.Direction.CW)
val radioHeight = (right - left) * arrowWeight
arrowPath.moveTo(
left + borderWidth + radioHeight - arrowHeight,
top + arrowHeight + borderWidth
)
arrowPath.lineTo(left + radioHeight + borderWidth, top.toFloat() + borderWidth)
arrowPath.lineTo(
left + arrowHeight + borderWidth + radioHeight,
top + arrowHeight + borderWidth
)
arrowPath.close()
} }
private fun drawLeftArrayWithRect(
left: Int,
top: Int,
right: Int,
bottom: Int
) {
rectF.set(
left.toFloat() + arrowHeight + borderWidth,
top.toFloat() + borderWidth,
right.toFloat() - borderWidth,
bottom.toFloat() - borderWidth
)
path.addRoundRect(rectF, radius, radius, Path.Direction.CW)
val radioHeight = (bottom - top) * arrowWeight
arrowPath.moveTo(left + arrowHeight + borderWidth, top + radioHeight + arrowHeight)
arrowPath.lineTo(left.toFloat() + borderWidth, top + radioHeight)
arrowPath.lineTo(left + arrowHeight + borderWidth, top + radioHeight - arrowHeight)
arrowPath.close()
// path.moveTo(left + arrowHeight, bottom - radius)
// val radioHeight = (bottom - top) * arrowWeight
// path.lineTo(left + arrowHeight, top + radioHeight + arrowHeight)
// path.lineTo(left.toFloat(), top + radioHeight)
// path.lineTo(left + arrowHeight, top + radioHeight - arrowHeight)
// path.lineTo(left + arrowHeight, top + radius)
//// // 话 左上的 圆弧
// path.addArc(
// RectF(
// left + arrowHeight,
// top.toFloat(),
// left + arrowHeight + 2 * radius,
// top + 2 * radius
// ),
// 180F,
// 90f
// )
// path.lineTo(right - radius, top.toFloat())
// path.addArc(
// RectF(right - 2 * radius, top.toFloat(), right.toFloat(), top + 2 * radius),
// 270F,
// 90f)
// path.lineTo(right.toFloat(), bottom - radius)
// path.addArc(
// RectF(
// right - 2 * radius,
// bottom - 2 * radius,
// right.toFloat(),
// bottom.toFloat()
// ), 0f, 90f
// )
// path.lineTo(left + arrowHeight + radius, bottom.toFloat())
// path.addArc(
// RectF(
// left + arrowHeight,
// bottom - radius,
// left + arrowHeight + 2 * radius,
// bottom.toFloat()
// ), 90f, 90f
// )
// path.close()
}
} }
\ No newline at end of file
package com.qimai.android.widgetlib.popup package com.qimai.android.widgetlib.popup
import android.graphics.Color
import android.graphics.Point
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.view.Gravity
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.PopupWindow
import androidx.annotation.IntDef
import androidx.core.view.ViewCompat
import com.qimai.android.widgetlib.R import com.qimai.android.widgetlib.R
/** /**
...@@ -10,21 +21,214 @@ import com.qimai.android.widgetlib.R ...@@ -10,21 +21,214 @@ import com.qimai.android.widgetlib.R
**/ **/
class QmToolTip private constructor( class QmToolTip private constructor(
var attachedView: View?, var attachedView: View?,
var defaultOverlayStyle: Int var defaultOverlayStyle: Int,
var gravity: Int
) { ) {
private val mWindow = PopupWindow()
private val attachedViewLocation = IntArray(2)
/**
* 箭头离 anchor的距离
*/
private val arrowOffsetOfAnchor = 20
/**
* 弹框边框离屏幕的距离
* 只有Tip 超过 最大高度和宽度的时候才会使用
*/
private val tipFrameOffsetOfScreenFrame = 20
private val containerPaddingBig = 30
private val containerPaddingSmall = 10
var containerMeasureWidth = 0
var containerMeasureHeight = 0
private constructor(builder: Builder) : this( private constructor(builder: Builder) : this(
builder.attachedView, builder.attachedView,
builder.defaultOverlayStyle builder.defaultOverlayStyle,
builder.gravity
) { ) {
checkMustParams(builder)
mWindow.width = ViewGroup.LayoutParams.WRAP_CONTENT
mWindow.height = ViewGroup.LayoutParams.WRAP_CONTENT
mWindow.isTouchable = true
mWindow.isFocusable = true
mWindow.isOutsideTouchable = true
gravity = builder.gravity
val container = FrameLayout(builder.contentView!!.context)
when (builder.gravity) {
Gravity.TOP -> {
container.setPadding(
containerPaddingSmall,
containerPaddingSmall,
containerPaddingSmall,
containerPaddingBig
)
}
Gravity.BOTTOM -> {
container.setPadding(
containerPaddingSmall,
containerPaddingBig,
containerPaddingSmall,
containerPaddingSmall
)
}
}
container.addView(
builder.contentView,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
container.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
containerMeasureWidth = container.measuredWidth
containerMeasureHeight = container.measuredHeight
builder.attachedView?.getLocationOnScreen(attachedViewLocation)
when (gravity) {
Gravity.TOP -> {
if (containerMeasureHeight > attachedViewLocation[1]) {
// view的上边放不下了
val containerParams = container.layoutParams
containerParams.height = attachedViewLocation[1] - 2 * arrowOffsetOfAnchor
container.layoutParams = containerParams
}
}
Gravity.BOTTOM -> {
if (containerMeasureHeight > attachedViewLocation[1]) {
// view的下边放不下了
val containerParams = container.layoutParams
containerParams.height = attachedViewLocation[1] - 2 * arrowOffsetOfAnchor
container.layoutParams = containerParams
}
}
}
container.background = QmTipOverlayDrawable(builder = builder)
mWindow.contentView = container
mWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
mWindow.setTouchInterceptor(View.OnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_OUTSIDE) {
mWindow.dismiss()
return@OnTouchListener false
}
false
})
mWindow.setOnDismissListener {
// this@QMBasePopup.onDismiss()
// if (mDismissListener != null) {
// mDismissListener!!.onDismiss()
// }
}
builder.attachedView?.addOnAttachStateChangeListener(object :
View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
}
override fun onViewDetachedFromWindow(v: View) {
if (hasShowing()) {
dismiss()
}
}
})
}
fun hasShowing(): Boolean {
return mWindow.isShowing
}
fun dismiss() {
mWindow.dismiss()
}
fun show() {
if (attachedView != null && !ViewCompat.isAttachedToWindow(attachedView!!)) {
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
mWindow.isAttachedInDecor = false
}
val point = calculateLocation(attachedView!!)
// showAsDropDown anchorView 的左下角 为原点 偏移 x, y
mWindow.showAtLocation(attachedView, Gravity.NO_GRAVITY, point.x, point.y)
}
private fun checkMustParams(builder: Builder) {
checkNotNull(builder.attachedView) {
"attachedView must not to be null "
}
}
private fun calculateLocation(anchorView: View): Point {
anchorView?.getLocationOnScreen(attachedViewLocation)
var point = Point()
when (gravity) {
Gravity.TOP -> {
point = calculateTopOffset(anchorView)
}
Gravity.BOTTOM -> {
point = calculateBottomOffset(anchorView)
}
}
return point
}
private fun calculateTopOffset(anchorView: View): Point {
val point = Point()
point.x =
(attachedViewLocation[0] + anchorView.measuredWidth / 2) - containerMeasureWidth / 2
point.y = attachedViewLocation[1] - arrowOffsetOfAnchor - anchorView.measuredHeight / 2
return point
}
private fun calculateBottomOffset(anchorView: View): Point {
val point = Point()
val anchorViewHeight = anchorView.measuredWidth
point.x = attachedViewLocation[0] + containerMeasureWidth / 2
point.y = attachedViewLocation[1] +anchorView.measuredHeight
return point
} }
class Builder { class Builder {
internal var attachedView: View? = null @IntDef(Gravity.TOP, Gravity.BOTTOM, Gravity.NO_GRAVITY)
@Retention(AnnotationRetention.SOURCE)
internal annotation class GravityRange
internal var attachedView: View? = null
internal var defaultOverlayStyle: Int = R.style.QmToolTipOverlayDefault internal var defaultOverlayStyle: Int = R.style.QmToolTipOverlayDefault
@GravityRange
internal var gravity = Gravity.NO_GRAVITY
internal var contentView: View? = null
fun withAttachedView(attachedView: View?) = apply { fun withAttachedView(attachedView: View?) = apply {
...@@ -32,11 +236,25 @@ class QmToolTip private constructor( ...@@ -32,11 +236,25 @@ class QmToolTip private constructor(
} }
fun withGravity(@GravityRange gravity: Int) = apply {
this.gravity = gravity
}
fun withDefaultOverlayStyle(defaultOverlayStyle: Int) = apply { fun withDefaultOverlayStyle(defaultOverlayStyle: Int) = apply {
this.defaultOverlayStyle = defaultOverlayStyle this.defaultOverlayStyle = defaultOverlayStyle
} }
fun withContentView(contentView: View) = apply {
this.contentView = contentView
}
fun build(): QmToolTip {
val tip = QmToolTip(this)
return tip
}
} }
} }
\ No newline at end of file
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<resources> <resources>
<style name="QmToolTipOverlayDefault"> <style name="QmToolTipOverlayDefault">
<item name="overlay_radius">4dp</item> <item name="overlay_radius">19dp</item>
<item name="overlay_bgColor">@color/QmTopBar_color_FFFFFFF</item> <item name="overlay_bgColor">@color/QmTopBar_color_FFFFFFF</item>
<item name="overlay_borderColor">@color/QmTopBar_color_FFFFFFF</item> <item name="overlay_borderColor">@color/color_777777</item>
<item name="overlay_borderWidth">1dp</item> <item name="overlay_borderWidth">0.5dp</item>
</style> </style>
</resources> </resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment