diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
index b66c20a3..b211fe73 100644
--- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
+++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
@@ -8,7 +8,12 @@ import android.location.Location;
import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
+
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewGroup;
import com.otaliastudios.cameraview.controls.Audio;
@@ -36,6 +41,7 @@ import com.otaliastudios.cameraview.internal.utils.Op;
import com.otaliastudios.cameraview.markers.AutoFocusMarker;
import com.otaliastudios.cameraview.markers.DefaultAutoFocusMarker;
import com.otaliastudios.cameraview.markers.MarkerLayout;
+import com.otaliastudios.cameraview.overlay.OverlayLayout;
import com.otaliastudios.cameraview.preview.MockCameraPreview;
import com.otaliastudios.cameraview.preview.CameraPreview;
import com.otaliastudios.cameraview.size.Size;
@@ -48,6 +54,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import org.w3c.dom.Attr;
import static org.junit.Assert.*;
@@ -777,5 +784,53 @@ public class CameraViewTest extends BaseTest {
//endregion
+ //region Overlays
+
+ @Test
+ public void testOverlays_generateLayoutParams() {
+ cameraView.mOverlayLayout = spy(cameraView.mOverlayLayout);
+ LayoutInflater inflater = LayoutInflater.from(context());
+ View overlay = inflater.inflate(com.otaliastudios.cameraview.test.R.layout.overlay, cameraView, false);
+ assertTrue(overlay.getLayoutParams() instanceof OverlayLayout.LayoutParams);
+ verify(cameraView.mOverlayLayout, times(1)).isOverlay(any(AttributeSet.class));
+ verify(cameraView.mOverlayLayout, times(1)).generateLayoutParams(any(AttributeSet.class));
+
+ }
+
+ @Test
+ public void testOverlays_dontGenerateLayoutParams() {
+ cameraView.mOverlayLayout = spy(cameraView.mOverlayLayout);
+ LayoutInflater inflater = LayoutInflater.from(context());
+ View overlay = inflater.inflate(com.otaliastudios.cameraview.test.R.layout.not_overlay, cameraView, false);
+ assertFalse(overlay.getLayoutParams() instanceof OverlayLayout.LayoutParams);
+ verify(cameraView.mOverlayLayout, times(1)).isOverlay(any(AttributeSet.class));
+ verify(cameraView.mOverlayLayout, never()).generateLayoutParams(any(AttributeSet.class));
+ }
+
+ @Test
+ public void testOverlays_addOverlayView() {
+ cameraView.mOverlayLayout = spy(cameraView.mOverlayLayout);
+ View overlay = new View(context());
+ OverlayLayout.LayoutParams params = new OverlayLayout.LayoutParams(10, 10, Gravity.CENTER);
+ int count = cameraView.getChildCount();
+ cameraView.addView(overlay, 0, params);
+ assertEquals(count, cameraView.getChildCount()); // Not added to CameraView
+ verify(cameraView.mOverlayLayout, times(1)).isOverlay(params);
+ verify(cameraView.mOverlayLayout, times(1)).addView(overlay, params);
+ }
+
+ @Test
+ public void testOverlays_dontAddOverlayView() {
+ cameraView.mOverlayLayout = spy(cameraView.mOverlayLayout);
+ View overlay = new View(context());
+ ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(10, 10);
+ int count = cameraView.getChildCount();
+ cameraView.addView(overlay, 0, params);
+ assertEquals(count + 1, cameraView.getChildCount());
+ verify(cameraView.mOverlayLayout, times(1)).isOverlay(params);
+ verify(cameraView.mOverlayLayout, never()).addView(overlay, params);
+ }
+
+ //endregion
// TODO: test permissions
}
diff --git a/cameraview/src/androidTest/res/layout/not_overlay.xml b/cameraview/src/androidTest/res/layout/not_overlay.xml
new file mode 100644
index 00000000..ba4fde4f
--- /dev/null
+++ b/cameraview/src/androidTest/res/layout/not_overlay.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/cameraview/src/androidTest/res/layout/overlay.xml b/cameraview/src/androidTest/res/layout/overlay.xml
new file mode 100644
index 00000000..4038e09f
--- /dev/null
+++ b/cameraview/src/androidTest/res/layout/overlay.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
index f42dcad0..d2ae9e03 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
@@ -127,14 +127,14 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
@VisibleForTesting ScrollGestureFinder mScrollGestureFinder;
// Views
- GridLinesLayout mGridLinesLayout;
- MarkerLayout mMarkerLayout;
+ @VisibleForTesting GridLinesLayout mGridLinesLayout;
+ @VisibleForTesting MarkerLayout mMarkerLayout;
private boolean mKeepScreenOn;
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private boolean mExperimental;
// Overlays
- private OverlayLayout mOverlayLayout;
+ @VisibleForTesting OverlayLayout mOverlayLayout;
// Threading
private Handler mUiHandler;
diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java
index cbf85915..d0acc44c 100644
--- a/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java
+++ b/cameraview/src/main/java/com/otaliastudios/cameraview/overlay/OverlayLayout.java
@@ -59,7 +59,7 @@ public class OverlayLayout extends FrameLayout implements Overlay {
* @return true if overlay
*/
public boolean isOverlay(@NonNull ViewGroup.LayoutParams params) {
- return params instanceof LayoutParams;
+ return params instanceof LayoutParams && (((LayoutParams) params).isOverlay);
}
/**
@@ -163,18 +163,24 @@ public class OverlayLayout extends FrameLayout implements Overlay {
@SuppressWarnings("unused")
private boolean isOverlay;
- public boolean drawOnPreview;
- public boolean drawOnPictureSnapshot;
- public boolean drawOnVideoSnapshot;
+ public boolean drawOnPreview = false;
+ public boolean drawOnPictureSnapshot = false;
+ public boolean drawOnVideoSnapshot = false;
- public LayoutParams(@NonNull Context context, @Nullable AttributeSet attrs) {
+ public LayoutParams(int width, int height, int gravity) {
+ super(width, height, gravity);
+ isOverlay = true;
+ }
+
+ public LayoutParams(@NonNull Context context, @NonNull AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView_Layout);
try {
- this.isOverlay = a.getBoolean(R.styleable.CameraView_Layout_layout_isOverlay, false);
- this.drawOnPreview = a.getBoolean(R.styleable.CameraView_Layout_layout_drawOnPreview, false);
- this.drawOnPictureSnapshot = a.getBoolean(R.styleable.CameraView_Layout_layout_drawOnPictureSnapshot, false);
- this.drawOnVideoSnapshot = a.getBoolean(R.styleable.CameraView_Layout_layout_drawOnVideoSnapshot, false);
+ // If someone is calling this constructor, they will likely want isOverlay to be true!
+ isOverlay = a.getBoolean(R.styleable.CameraView_Layout_layout_isOverlay, true);
+ drawOnPreview = a.getBoolean(R.styleable.CameraView_Layout_layout_drawOnPreview, false);
+ drawOnPictureSnapshot = a.getBoolean(R.styleable.CameraView_Layout_layout_drawOnPictureSnapshot, false);
+ drawOnVideoSnapshot = a.getBoolean(R.styleable.CameraView_Layout_layout_drawOnVideoSnapshot, false);
} finally {
a.recycle();
}
diff --git a/demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java b/demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java
index 425b2fc7..c9ce8220 100644
--- a/demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java
+++ b/demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java
@@ -84,7 +84,8 @@ public class CameraActivity extends AppCompatActivity implements View.OnClickLis
new Option.Pinch(), new Option.HorizontalScroll(), new Option.VerticalScroll(),
new Option.Tap(), new Option.LongTap(),
// Watermarks
- new Option.OverlayInPreview(watermark), new Option.OverlayInPictureSnapshot(watermark),
+ new Option.OverlayInPreview(watermark),
+ new Option.OverlayInPictureSnapshot(watermark),
new Option.OverlayInVideoSnapshot(watermark),
// Other
new Option.Grid(), new Option.GridColor(), new Option.UseDeviceOrientation()
@@ -122,14 +123,12 @@ public class CameraActivity extends AppCompatActivity implements View.OnClickLis
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- float rotation = 0;
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (float) animation.getAnimatedValue();
- rotation += 2;
watermark.setScaleX(scale);
watermark.setScaleY(scale);
- watermark.setRotation(rotation);
+ watermark.setRotation(watermark.getRotation() + 2);
}
});
animator.start();