Skip to content

Commit d4bfd43

Browse files
author
fengpeng
committed
java version
1 parent ad849f7 commit d4bfd43

File tree

12 files changed

+528
-418
lines changed

12 files changed

+528
-418
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ class MainActivity : AppCompatActivity() {
3939

4040
private fun buildMultiOverlay() {
4141
val overlay1 = Overlay.Builder()
42-
.anchor(Anchor.rect(R.id.tv1, radius = 10, outset = 10))
42+
.anchor(Anchor.rect(R.id.tv1, 10, 10))
4343
.marker(R.layout.tv1_marker)
4444
.build()
4545
overlay1.marker(R.layout.tv1_marker, m1Layout)
4646
val overlay2 = Overlay.Builder()
47-
.anchor(Anchor.circle(R.id.tv2, outset = 30))
47+
.anchor(Anchor.circle(R.id.tv2, 30))
4848
.marker(R.layout.tv2_marker)
4949
.build()
5050
overlay2.marker(R.layout.tv2_marker, m2Layout)
@@ -53,21 +53,21 @@ class MainActivity : AppCompatActivity() {
5353

5454
private fun buildMultiAnchor() {
5555
val overlay = Overlay.Builder()
56-
.anchor(Anchor.rect(R.id.tv1, radius = 10, outset = 5))
56+
.anchor(Anchor.rect(R.id.tv1, 10, 5))
5757
.marker(R.layout.tv1_marker)
58-
.anchor(Anchor.circle(R.id.tv2, outset = 20))
58+
.anchor(Anchor.circle(R.id.tv2, 20))
5959
.marker(R.layout.tv2_marker)
6060
//
61-
.anchor(Anchor.rect(R.id.vRecycler, radius = 10, outset = 5))
61+
.anchor(Anchor.rect(R.id.vRecycler, 10, 5))
6262
.marker(R.id.vRecycler, Marker.iv(baseContext, R.mipmap.ic_launcher))
6363
.build()
6464
overlay.marker(R.layout.tv1_marker, m1Layout)
6565
overlay.marker(R.layout.tv2_marker, m2Layout)
6666
overlay.marker(R.id.vRecycler, object : Marker.MarkerLayout() {
6767
override fun onLayout(cs: ConstraintSet, marker: View, anchor: View) {
6868
super.onLayout(cs, marker, anchor)
69-
connect(ConstraintSet.START)
70-
connect(ConstraintSet.END)
69+
connect(ConstraintSet.START, 0)
70+
connect(ConstraintSet.END, 0)
7171
connect(ConstraintSet.BOTTOM, ConstraintSet.TOP, 10)
7272
}
7373
})
@@ -84,8 +84,8 @@ class MainActivity : AppCompatActivity() {
8484
private val m1Layout: Marker.MarkerLayout = object : Marker.MarkerLayout() {
8585
override fun onLayout(cs: ConstraintSet, marker: View, anchor: View) {
8686
super.onLayout(cs, marker, anchor)
87-
connect(ConstraintSet.START)
88-
connect(ConstraintSet.END)
87+
connect(ConstraintSet.START, 0)
88+
connect(ConstraintSet.END, 0)
8989
connect(ConstraintSet.TOP, ConstraintSet.BOTTOM, 20)
9090
setClickListener(R.id.btNext) { adapter.next() }
9191
}
@@ -94,8 +94,8 @@ class MainActivity : AppCompatActivity() {
9494
private val m2Layout: Marker.MarkerLayout = object : Marker.MarkerLayout() {
9595
override fun onLayout(cs: ConstraintSet, marker: View, anchor: View) {
9696
super.onLayout(cs, marker, anchor)
97-
connect(ConstraintSet.START)
98-
connect(ConstraintSet.END)
97+
connect(ConstraintSet.START, 0)
98+
connect(ConstraintSet.END, 0)
9999
connect(ConstraintSet.TOP, ConstraintSet.BOTTOM, 20)
100100
setParentClickListener { adapter.next() }
101101
}

lib/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
plugins {
22
id 'com.android.library'
3-
id 'kotlin-android'
43
}
54

65
android {
@@ -30,7 +29,6 @@ android {
3029
}
3130

3231
dependencies {
33-
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
3432
implementation 'androidx.core:core-ktx:1.3.2'
3533
implementation 'androidx.appcompat:appcompat:1.2.0'
3634
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.pizzk.overlay;
2+
3+
import com.pizzk.overlay.el.Overlay;
4+
5+
import java.util.Arrays;
6+
import java.util.LinkedList;
7+
import java.util.List;
8+
9+
public class OverlayAdapter {
10+
private final List<Overlay> overlays = new LinkedList<>();
11+
private OverlayLayout view = null;
12+
13+
public OverlayAdapter with(OverlayLayout v) {
14+
view = v;
15+
return this;
16+
}
17+
18+
public OverlayAdapter overlays(List<Overlay> v) {
19+
overlays.clear();
20+
if (null == v) return this;
21+
overlays.addAll(v);
22+
return this;
23+
}
24+
25+
public OverlayAdapter overlays(Overlay... vs) {
26+
if (null == vs || vs.length <= 0) return this;
27+
return overlays(Arrays.asList(vs));
28+
}
29+
30+
public boolean next() {
31+
if (null == view) return false;
32+
if (overlays.isEmpty()) {
33+
view.setOverlay(null);
34+
view.setVisibility(false);
35+
return false;
36+
}
37+
view.setVisibility(true);
38+
view.setOverlay(overlays.remove(0));
39+
return true;
40+
}
41+
42+
public void finish() {
43+
overlays.clear();
44+
next();
45+
}
46+
}

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

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package com.pizzk.overlay;
2+
3+
import android.annotation.SuppressLint;
4+
import android.content.Context;
5+
import android.graphics.Bitmap;
6+
import android.graphics.Canvas;
7+
import android.graphics.Color;
8+
import android.graphics.Paint;
9+
import android.graphics.PorterDuff;
10+
import android.graphics.PorterDuffXfermode;
11+
import android.graphics.RectF;
12+
import android.util.AttributeSet;
13+
import android.view.View;
14+
import android.view.ViewGroup;
15+
import android.view.ViewParent;
16+
17+
import androidx.annotation.ColorRes;
18+
import androidx.annotation.NonNull;
19+
import androidx.annotation.Nullable;
20+
import androidx.constraintlayout.widget.ConstraintLayout;
21+
import androidx.constraintlayout.widget.ConstraintSet;
22+
import androidx.core.content.ContextCompat;
23+
24+
import com.pizzk.overlay.el.Anchor;
25+
import com.pizzk.overlay.el.Marker;
26+
import com.pizzk.overlay.el.Overlay;
27+
28+
public class OverlayLayout extends ConstraintLayout {
29+
private final Paint paint = new Paint();
30+
private final RectF rect = new RectF();
31+
private int maskColor = Color.TRANSPARENT;
32+
private Bitmap bitmap = null;
33+
34+
public OverlayLayout(@NonNull Context context) {
35+
this(context, null);
36+
}
37+
38+
public OverlayLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
39+
this(context, attrs, 0);
40+
}
41+
42+
public OverlayLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
43+
super(context, attrs, defStyleAttr);
44+
paint.setColor(Color.TRANSPARENT);
45+
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
46+
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
47+
setWillNotDraw(false);
48+
setClickable(true);
49+
setMaskColor(R.color.overlay_mask);
50+
}
51+
52+
public void setMaskColor(@ColorRes int colorId) {
53+
maskColor = ContextCompat.getColor(getContext(), colorId);
54+
}
55+
56+
public void setOverlay(Overlay overlay) {
57+
removeAllViews();
58+
setOnClickListener(null);
59+
if (null == overlay) return;
60+
ViewParent p = getParent();
61+
if (!(p instanceof ViewGroup)) return;
62+
ViewGroup view = (ViewGroup) p;
63+
post(() -> {
64+
try {
65+
onChangeLayout(view, overlay);
66+
} catch (Exception e) {
67+
e.printStackTrace();
68+
}
69+
});
70+
}
71+
72+
public void setVisibility(boolean v) {
73+
if (v == (View.VISIBLE == getVisibility())) return;
74+
setVisibility(v ? View.VISIBLE : View.GONE);
75+
}
76+
77+
private void onChangeLayout(ViewGroup viewGroup, Overlay overlay) {
78+
//准备画布
79+
80+
Bitmap bmp = null != bitmap ? bitmap : Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
81+
bitmap = bmp;
82+
bmp.eraseColor(Color.TRANSPARENT);
83+
Canvas canvas = new Canvas(bmp);
84+
canvas.drawColor(maskColor);
85+
//计算位置
86+
int[] vXY = new int[2];
87+
getLocationOnScreen(vXY);
88+
int[] vAnchorXY = new int[2];
89+
for (Anchor e : overlay.anchors) {
90+
View vAnchor = e.getFind().onFind(viewGroup, e);
91+
if (null == vAnchor) return;
92+
//计算宽度及位置
93+
vAnchor.getLocationOnScreen(vAnchorXY);
94+
rect.left = vAnchorXY[0] - vXY[0] - 0f;
95+
rect.top = vAnchorXY[1] - vXY[1] - 0f;
96+
rect.right = rect.left + vAnchor.getWidth();
97+
rect.bottom = rect.top + vAnchor.getHeight();
98+
//镂空样式
99+
rect.inset(-e.outset, -e.outset);
100+
//锚点生产及绘制
101+
e.getDraw().onDraw(canvas, paint, e, rect);
102+
View anchor = onFakeAnchor(e.id, rect);
103+
//标记层布局
104+
for (Marker marker : overlay.markers) {
105+
if (marker.anchor != e.id) continue;
106+
onLayoutMarker(viewGroup.getContext(), marker, anchor);
107+
}
108+
}
109+
}
110+
111+
private View onFakeAnchor(int id, RectF rc) {
112+
View v = getViewById(id);
113+
if (null != v) return v;
114+
View view = new View(getContext());
115+
view.setId(id);
116+
addView(view, (int) rc.width(), (int) rc.height());
117+
ConstraintSet cs = new ConstraintSet();
118+
cs.clone(this);
119+
int iid = ConstraintSet.PARENT_ID;
120+
cs.connect(id, ConstraintSet.START, iid, ConstraintSet.START, (int) rc.left);
121+
cs.connect(id, ConstraintSet.TOP, iid, ConstraintSet.TOP, (int) rc.top);
122+
cs.applyTo(this);
123+
return view;
124+
}
125+
126+
@SuppressLint("ResourceType")
127+
private void onLayoutMarker(Context context, Marker marker, View anchor) {
128+
View v = marker.getMake().onMake(context, marker);
129+
if (null == v) return;
130+
if (v.getId() <= 0) v.setId(marker.id + marker.hashCode());
131+
addView(v);
132+
ConstraintSet cs = new ConstraintSet();
133+
cs.clone(this);
134+
marker.getLayout().onLayout(cs, v, anchor);
135+
cs.applyTo(this);
136+
}
137+
138+
@Override
139+
protected void onDraw(Canvas canvas) {
140+
if (null != bitmap && null != canvas) {
141+
canvas.drawBitmap(bitmap, 0f, 0f, null);
142+
}
143+
super.onDraw(canvas);
144+
}
145+
146+
@Override
147+
protected void onDetachedFromWindow() {
148+
super.onDetachedFromWindow();
149+
if (null != bitmap) bitmap.recycle();
150+
bitmap = null;
151+
}
152+
}

0 commit comments

Comments
 (0)