Skip to content

Commit 46ae8ce

Browse files
author
fengpeng
committed
Anchor add Find
1 parent 9854005 commit 46ae8ce

File tree

7 files changed

+90
-19
lines changed

7 files changed

+90
-19
lines changed

app/src/main/java/com/pizzk/overlay/app/MainActivity.kt

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.pizzk.overlay.app
22

3+
import android.graphics.Color
34
import androidx.appcompat.app.AppCompatActivity
45
import android.os.Bundle
56
import android.view.View
6-
import android.widget.Toast
7+
import android.view.ViewGroup
78
import androidx.constraintlayout.widget.ConstraintSet
9+
import androidx.recyclerview.widget.LinearLayoutManager
10+
import androidx.recyclerview.widget.RecyclerView
811
import com.pizzk.overlay.*
912
import com.pizzk.overlay.el.Anchor
1013
import com.pizzk.overlay.el.Marker
@@ -16,30 +19,32 @@ class MainActivity : AppCompatActivity() {
1619
override fun onCreate(savedInstanceState: Bundle?) {
1720
super.onCreate(savedInstanceState)
1821
setContentView(R.layout.activity_main)
22+
val rv: RecyclerView = findViewById(R.id.vRecycler)
23+
rv.layoutManager = LinearLayoutManager(baseContext)
24+
rv.adapter = ListAdapter()
25+
//
1926
val vOverlay: OverlayLayout = findViewById(R.id.vOverlay)
2027
vOverlay.setMaskColor(R.color.overlay_mask)
2128
vOverlay.setVisibility(false)
2229
adapter.with(vOverlay)
2330
findViewById<View>(R.id.tv1).setOnClickListener {
24-
Toast.makeText(baseContext, "TV1 clicked", Toast.LENGTH_SHORT).show()
2531
buildMultiOverlay()
2632
adapter.next()
2733
}
2834
findViewById<View>(R.id.tv2).setOnClickListener {
29-
Toast.makeText(baseContext, "TV2 clicked", Toast.LENGTH_SHORT).show()
3035
buildMultiAnchor()
3136
adapter.next()
3237
}
3338
}
3439

3540
private fun buildMultiOverlay() {
3641
val overlay1 = Overlay.Builder()
37-
.anchor(Anchor.rect(R.id.tv1, radius = 10, inset = 10))
42+
.anchor(Anchor.rect(R.id.tv1, radius = 10, outset = 10))
3843
.marker(R.layout.tv1_marker)
3944
.build()
4045
overlay1.marker(R.layout.tv1_marker, m1Layout)
4146
val overlay2 = Overlay.Builder()
42-
.anchor(Anchor.circle(R.id.tv2, inset = 30))
47+
.anchor(Anchor.circle(R.id.tv2, outset = 30))
4348
.marker(R.layout.tv2_marker)
4449
.build()
4550
overlay2.marker(R.layout.tv2_marker, m2Layout)
@@ -48,14 +53,23 @@ class MainActivity : AppCompatActivity() {
4853

4954
private fun buildMultiAnchor() {
5055
val overlay = Overlay.Builder()
51-
.anchor(Anchor.rect(R.id.tv1, radius = 10, inset = 5))
56+
.anchor(Anchor.rect(R.id.tv1, radius = 10, outset = 5))
5257
.marker(R.layout.tv1_marker)
53-
.anchor(Anchor.circle(R.id.tv2, inset = 20))
58+
.anchor(Anchor.circle(R.id.tv2, outset = 20))
5459
.marker(R.layout.tv2_marker)
60+
//
61+
.anchor(Anchor.rect(R.id.vRecycler, radius = 10, outset = 5))
5562
.build()
5663
overlay.marker(R.layout.tv1_marker, m1Layout)
5764
overlay.marker(R.layout.tv2_marker, m2Layout)
58-
adapter.overlays(listOf(overlay))
65+
//特殊情况:从RecyclerView中获取定位子元素,不能使用使用常规的findViewById
66+
overlay.anchor(R.id.vRecycler, object : Anchor.Find {
67+
override fun onFind(parent: ViewGroup, id: Int): View? {
68+
val v: ViewGroup? = findViewById(id)
69+
return v?.getChildAt(2)
70+
}
71+
})
72+
adapter.overlays(overlay)
5973
}
6074

6175
private val m1Layout: Marker.MarkerLayout = object : Marker.MarkerLayout() {
@@ -77,4 +91,21 @@ class MainActivity : AppCompatActivity() {
7791
setParentClickListener { adapter.next() }
7892
}
7993
}
94+
95+
private class ListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
96+
private val colors: List<Int> = listOf(Color.RED, Color.GREEN, Color.BLUE)
97+
98+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
99+
val v = View(parent.context)
100+
val lp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200)
101+
v.layoutParams = lp
102+
return object : RecyclerView.ViewHolder(v) {}
103+
}
104+
105+
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
106+
holder.itemView.setBackgroundColor(colors[position % colors.size])
107+
}
108+
109+
override fun getItemCount(): Int = 4
110+
}
80111
}

app/src/main/res/layout/activity_main.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@
3737
app:layout_constraintTop_toTopOf="parent"
3838
tools:ignore="HardcodedText" />
3939

40+
<androidx.recyclerview.widget.RecyclerView
41+
android:id="@+id/vRecycler"
42+
android:layout_width="match_parent"
43+
android:layout_height="wrap_content"
44+
android:layout_marginTop="60dp"
45+
app:layout_constraintEnd_toEndOf="parent"
46+
app:layout_constraintStart_toStartOf="parent"
47+
app:layout_constraintTop_toBottomOf="@+id/tv2" />
48+
4049

4150
<com.pizzk.overlay.OverlayLayout
4251
android:id="@+id/vOverlay"

lib/src/main/java/com/pizzk/overlay/OverlayAdapter.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,24 @@ class OverlayAdapter {
1717
return this
1818
}
1919

20+
fun overlays(vararg vs: Overlay): OverlayAdapter {
21+
return overlays(vs.toList())
22+
}
23+
2024
fun next(): Boolean {
2125
val view: OverlayLayout = view ?: return false
2226
if (overlays.isEmpty()) {
27+
view.setOverlay(null)
2328
view.setVisibility(false)
2429
return false
2530
}
2631
view.setVisibility(true)
2732
view.setOverlay(overlays.removeAt(0))
2833
return true
2934
}
35+
36+
fun finish() {
37+
overlays.clear()
38+
next()
39+
}
3040
}

lib/src/main/java/com/pizzk/overlay/OverlayLayout.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,16 @@ class OverlayLayout : ConstraintLayout {
7373
//
7474
val lf = LayoutInflater.from(viewGroup.context)
7575
overlay.anchors.forEach { e: Anchor ->
76-
val vAnchor: View = viewGroup.findViewById(e.id)
76+
val vAnchor: View = e.find.onFind(viewGroup, e.id) ?: return@forEach
7777
//计算宽度及位置
7878
vAnchor.getLocationOnScreen(vAnchorXY)
7979
rect.left = vAnchorXY[0] - vXY[0] - 0f
8080
rect.top = vAnchorXY[1] - vXY[1] - 0f
8181
rect.right = rect.left + vAnchor.width
8282
rect.bottom = rect.top + vAnchor.height
8383
//镂空样式
84-
val inset = e.inset.toFloat()
85-
rect.inset(-inset, -inset)
84+
val outset = e.outset.toFloat()
85+
rect.inset(-outset, -outset)
8686
//锚点生产及绘制
8787
e.draw.onDraw(canvas, paint, e, rect)
8888
val anchor = onFakeAnchor(e.id, rect.toRect())

lib/src/main/java/com/pizzk/overlay/el/Anchor.kt

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.pizzk.overlay.el
33
import android.graphics.Canvas
44
import android.graphics.Paint
55
import android.graphics.RectF
6+
import android.view.View
7+
import android.view.ViewGroup
68
import androidx.annotation.IdRes
79

810
/**
@@ -13,9 +15,10 @@ class Anchor(
1315
val id: Int,
1416
val radius: Int,
1517
val circle: Boolean,
16-
val inset: Int
18+
val outset: Int
1719
) {
18-
var draw: Draw = delegateDraw
20+
internal var draw: Draw = delegateDraw
21+
internal var find: Find = delegateFind
1922

2023
/**
2124
* 锚点绘制接口
@@ -24,6 +27,13 @@ class Anchor(
2427
fun onDraw(canvas: Canvas, paint: Paint, e: Anchor, rect: RectF)
2528
}
2629

30+
/**
31+
* 锚点查找接口,默认使用findViewById,可自定义实现查找匹配
32+
*/
33+
interface Find {
34+
fun onFind(parent: ViewGroup, @IdRes id: Int): View?
35+
}
36+
2737
/**
2838
* 默认支持绘制圆形和矩形
2939
*/
@@ -46,21 +56,28 @@ class Anchor(
4656
}
4757
}
4858

59+
class AnchorFind : Find {
60+
override fun onFind(parent: ViewGroup, @IdRes id: Int): View? {
61+
return parent.findViewById(id)
62+
}
63+
}
64+
4965
companion object {
5066
private val delegateDraw: Draw by lazy { AnchorDraw() }
67+
private val delegateFind: Find by lazy { AnchorFind() }
5168

5269
/**
5370
* 构建矩形锚点
5471
*/
55-
fun rect(@IdRes id: Int, radius: Int = 0, inset: Int = 0): Anchor {
56-
return Anchor(id, radius, circle = false, inset)
72+
fun rect(@IdRes id: Int, radius: Int = 0, outset: Int = 0): Anchor {
73+
return Anchor(id, radius, circle = false, outset)
5774
}
5875

5976
/**
6077
* 构建圆形锚点
6178
*/
62-
fun circle(@IdRes id: Int, inset: Int = 0): Anchor {
63-
return Anchor(id, radius = 0, circle = true, inset)
79+
fun circle(@IdRes id: Int, outset: Int = 0): Anchor {
80+
return Anchor(id, radius = 0, circle = true, outset)
6481
}
6582
}
6683
}

lib/src/main/java/com/pizzk/overlay/el/Marker.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Marker(
1212
@IdRes
1313
val anchor: Int
1414
) {
15-
var layout: Layout = delegateLayout
15+
internal var layout: Layout = delegateLayout
1616

1717
interface Layout {
1818
fun onLayout(cs: ConstraintSet, marker: View, anchor: View)

lib/src/main/java/com/pizzk/overlay/el/Overlay.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.pizzk.overlay.el
33
import androidx.annotation.IdRes
44
import androidx.annotation.LayoutRes
55

6-
76
class Overlay(val anchors: List<Anchor>, val markers: List<Marker>) {
87

98
class Builder {
@@ -35,6 +34,11 @@ class Overlay(val anchors: List<Anchor>, val markers: List<Marker>) {
3534
anchor.draw = draw
3635
}
3736

37+
fun anchor(@IdRes id: Int, find: Anchor.Find) {
38+
val anchor = anchors.find { it.id == id } ?: return
39+
anchor.find = find
40+
}
41+
3842
fun marker(@LayoutRes id: Int, layout: Marker.Layout) {
3943
val marker = markers.find { it.id == id } ?: return
4044
marker.layout = layout

0 commit comments

Comments
 (0)