zkit-ui 2.0.4 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +56 -0
  2. package/android/build.gradle +100 -0
  3. package/android/src/main/AndroidManifest.xml +1 -0
  4. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewLayoutSupport.java +450 -0
  5. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewMediaItem.java +36 -0
  6. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewModule.kt +43 -0
  7. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewPagerAdapter.java +140 -0
  8. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewSharedElementGeometry.java +25 -0
  9. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewSharedElementNames.java +39 -0
  10. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewSharedElementState.java +25 -0
  11. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewSourceViewRegistry.java +115 -0
  12. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewTransitionSnapshotView.java +60 -0
  13. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewVideoPlayerView.java +338 -0
  14. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewView.kt +305 -0
  15. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewViewerOverlayView.java +636 -0
  16. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewViewerPageView.java +357 -0
  17. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewViewerTransitionController.java +223 -0
  18. package/android/src/main/res/layout/native_image_preview_player_view.xml +9 -0
  19. package/dist/all.d.ts +2 -0
  20. package/dist/all.d.ts.map +1 -1
  21. package/dist/all.js +24 -22
  22. package/dist/ui/NativeImagePreview/NativeImagePreview.d.ts +3 -0
  23. package/dist/ui/NativeImagePreview/NativeImagePreview.d.ts.map +1 -0
  24. package/dist/ui/NativeImagePreview/NativeImagePreview.js +99 -0
  25. package/dist/ui/NativeImagePreview/NativeImagePreview.web.d.ts +4 -0
  26. package/dist/ui/NativeImagePreview/NativeImagePreview.web.d.ts.map +1 -0
  27. package/dist/ui/NativeImagePreview/NativeImagePreview.web.js +150 -0
  28. package/dist/ui/NativeImagePreview/context.d.ts +14 -0
  29. package/dist/ui/NativeImagePreview/context.d.ts.map +1 -0
  30. package/dist/ui/NativeImagePreview/context.js +38 -0
  31. package/dist/ui/NativeImagePreview/index.d.ts +3 -0
  32. package/dist/ui/NativeImagePreview/index.d.ts.map +1 -0
  33. package/dist/ui/NativeImagePreview/index.js +5 -0
  34. package/dist/ui/NativeImagePreview/types.d.ts +68 -0
  35. package/dist/ui/NativeImagePreview/types.d.ts.map +1 -0
  36. package/dist/ui/NativeImagePreview/types.js +2 -0
  37. package/dist/ui/NativeImagePreview/utils.d.ts +8 -0
  38. package/dist/ui/NativeImagePreview/utils.d.ts.map +1 -0
  39. package/dist/ui/NativeImagePreview/utils.js +83 -0
  40. package/dist/ui/NativeImagePreview/web/geometry.d.ts +20 -0
  41. package/dist/ui/NativeImagePreview/web/geometry.d.ts.map +1 -0
  42. package/dist/ui/NativeImagePreview/web/geometry.js +121 -0
  43. package/dist/ui/NativeImagePreview/web/media.d.ts +6 -0
  44. package/dist/ui/NativeImagePreview/web/media.d.ts.map +1 -0
  45. package/dist/ui/NativeImagePreview/web/media.js +90 -0
  46. package/dist/ui/NativeImagePreview/web/styles.css +137 -0
  47. package/dist/ui/NativeImagePreview/web/transition.d.ts +15 -0
  48. package/dist/ui/NativeImagePreview/web/transition.d.ts.map +1 -0
  49. package/dist/ui/NativeImagePreview/web/transition.js +77 -0
  50. package/dist/ui/NativeImagePreview/web/types.d.ts +74 -0
  51. package/dist/ui/NativeImagePreview/web/types.d.ts.map +1 -0
  52. package/dist/ui/NativeImagePreview/web/types.js +3 -0
  53. package/dist/ui/NativeImagePreview/web/viewer.d.ts +104 -0
  54. package/dist/ui/NativeImagePreview/web/viewer.d.ts.map +1 -0
  55. package/dist/ui/NativeImagePreview/web/viewer.js +894 -0
  56. package/expo-module.config.json +11 -0
  57. package/ios/NativeImagePreview/NativeImagePreviewImageLoader.swift +73 -0
  58. package/ios/NativeImagePreview/NativeImagePreviewImageViewInteraction.swift +245 -0
  59. package/ios/NativeImagePreview/NativeImagePreviewLayoutSupport.swift +143 -0
  60. package/ios/NativeImagePreview/NativeImagePreviewMedia.swift +28 -0
  61. package/ios/NativeImagePreview/NativeImagePreviewSourceViewRegistry.swift +80 -0
  62. package/ios/NativeImagePreview/NativeImagePreviewVideoPlayerView.swift +437 -0
  63. package/ios/NativeImagePreview/NativeImagePreviewViewerConfiguration.swift +51 -0
  64. package/ios/NativeImagePreview/NativeImagePreviewViewerController.swift +745 -0
  65. package/ios/NativeImagePreview/NativeImagePreviewViewerPageView.swift +623 -0
  66. package/ios/NativeImagePreview/NativeImagePreviewViewerTransitionCoordinator.swift +312 -0
  67. package/ios/NativeImagePreviewModule.swift +46 -0
  68. package/ios/NativeImagePreviewView.swift +252 -0
  69. package/package.json +16 -2
  70. package/src/all.ts +18 -0
  71. package/src/services/ImagePreviewService/README.md +19 -0
  72. package/src/types.d.ts +1 -0
  73. package/src/ui/NativeImagePreview/NativeImagePreview.tsx +146 -0
  74. package/src/ui/NativeImagePreview/NativeImagePreview.web.tsx +201 -0
  75. package/src/ui/NativeImagePreview/README.md +111 -0
  76. package/src/ui/NativeImagePreview/context.tsx +22 -0
  77. package/src/ui/NativeImagePreview/index.tsx +18 -0
  78. package/src/ui/NativeImagePreview/types.ts +94 -0
  79. package/src/ui/NativeImagePreview/utils.ts +108 -0
  80. package/src/ui/NativeImagePreview/web/geometry.ts +134 -0
  81. package/src/ui/NativeImagePreview/web/media.ts +91 -0
  82. package/src/ui/NativeImagePreview/web/styles.css +137 -0
  83. package/src/ui/NativeImagePreview/web/transition.ts +111 -0
  84. package/src/ui/NativeImagePreview/web/types.ts +88 -0
  85. package/src/ui/NativeImagePreview/web/viewer.ts +1024 -0
  86. package/zkit-ui.podspec +13 -1
@@ -0,0 +1,43 @@
1
+ package cn.fontree.zkit.ui.preview
2
+
3
+ import expo.modules.kotlin.modules.Module
4
+ import expo.modules.kotlin.modules.ModuleDefinition
5
+
6
+ class NativeImagePreviewModule : Module() {
7
+ override fun definition() = ModuleDefinition {
8
+ Name("ZKitNativeImagePreview")
9
+
10
+ View(NativeImagePreviewView::class) {
11
+ Events(
12
+ "onIndexChange"
13
+ )
14
+ Prop("theme") { view: NativeImagePreviewView, theme: Theme ->
15
+ view.theme = theme
16
+ }
17
+ Prop("items") { view: NativeImagePreviewView, items: Array<Map<String, Any?>> ->
18
+ view.items = items.toList()
19
+ }
20
+ Prop("urls") { view: NativeImagePreviewView, urls: Array<String> ->
21
+ view.urls = urls
22
+ }
23
+ Prop("index") { view: NativeImagePreviewView, index: Int ->
24
+ view.initialIndex = index
25
+ }
26
+ Prop("previewGroupId") { view: NativeImagePreviewView, previewGroupId: String? ->
27
+ view.previewGroupId = previewGroupId
28
+ }
29
+ Prop("disableHiddenOriginalImage") { view: NativeImagePreviewView, disableHiddenOriginalImage: Boolean ->
30
+ view.disableHiddenOriginalImage = disableHiddenOriginalImage
31
+ }
32
+ Prop("edgeToEdge") { view: NativeImagePreviewView, edgeToEdge: Boolean ->
33
+ view.edgeToEdge = edgeToEdge
34
+ }
35
+ Prop("transitionOffsetY") { view: NativeImagePreviewView, transitionOffsetY: Int? ->
36
+ view.transitionOffsetY = transitionOffsetY
37
+ }
38
+ Prop("transitionOffsetX") { view: NativeImagePreviewView, transitionOffsetX: Int? ->
39
+ view.transitionOffsetX = transitionOffsetX
40
+ }
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,140 @@
1
+ package cn.fontree.zkit.ui.preview;
2
+
3
+ import android.view.ViewGroup;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
7
+ import androidx.recyclerview.widget.RecyclerView;
8
+
9
+ import java.util.ArrayList;
10
+ import java.util.HashMap;
11
+ import java.util.List;
12
+ import java.util.Map;
13
+
14
+ public final class NativeImagePreviewPagerAdapter extends RecyclerView.Adapter<NativeImagePreviewPagerAdapter.PageViewHolder> {
15
+ public interface PageBindCallback {
16
+ void onPageBound(@NonNull NativeImagePreviewViewerPageView pageView, int position);
17
+ }
18
+
19
+ private final List<NativeImagePreviewMediaItem> items = new ArrayList<>();
20
+ private final Map<Integer, NativeImagePreviewViewerPageView> attachedViews = new HashMap<>();
21
+ @Nullable
22
+ private final NativeImagePreviewViewerPageView.Listener pageListener;
23
+ @Nullable
24
+ private final PageBindCallback pageBindCallback;
25
+ private int activeIndex = -1;
26
+
27
+ public NativeImagePreviewPagerAdapter(
28
+ @Nullable NativeImagePreviewViewerPageView.Listener pageListener,
29
+ @Nullable PageBindCallback pageBindCallback
30
+ ) {
31
+ this.pageListener = pageListener;
32
+ this.pageBindCallback = pageBindCallback;
33
+ }
34
+
35
+ public void setItems(@NonNull List<NativeImagePreviewMediaItem> list) {
36
+ attachedViews.clear();
37
+ items.clear();
38
+ items.addAll(list);
39
+ notifyDataSetChanged();
40
+ }
41
+
42
+ public void setActiveIndex(int index) {
43
+ activeIndex = index;
44
+ for (Map.Entry<Integer, NativeImagePreviewViewerPageView> entry : attachedViews.entrySet()) {
45
+ entry.getValue().setActive(entry.getKey() == index);
46
+ }
47
+ }
48
+
49
+ public void releaseAll() {
50
+ for (NativeImagePreviewViewerPageView view : attachedViews.values()) {
51
+ view.release();
52
+ }
53
+ attachedViews.clear();
54
+ }
55
+
56
+ @Nullable
57
+ public NativeImagePreviewViewerPageView findAttachedView(int position) {
58
+ NativeImagePreviewViewerPageView pageView = attachedViews.get(position);
59
+ if (pageView == null) {
60
+ return null;
61
+ }
62
+ if (!pageView.isAttachedToWindow()) {
63
+ attachedViews.remove(position);
64
+ return null;
65
+ }
66
+ return pageView;
67
+ }
68
+
69
+ @Nullable
70
+ public NativeImagePreviewViewerPageView findActiveView() {
71
+ return attachedViews.get(activeIndex);
72
+ }
73
+
74
+ @NonNull
75
+ @Override
76
+ public PageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
77
+ NativeImagePreviewViewerPageView pageView = new NativeImagePreviewViewerPageView(parent.getContext());
78
+ pageView.setListener(pageListener);
79
+ return new PageViewHolder(pageView);
80
+ }
81
+
82
+ @Override
83
+ public void onBindViewHolder(@NonNull PageViewHolder holder, int position) {
84
+ holder.pageView.bind(items.get(position));
85
+ if (pageBindCallback != null) {
86
+ pageBindCallback.onPageBound(holder.pageView, position);
87
+ }
88
+ holder.pageView.setActive(position == activeIndex);
89
+ }
90
+
91
+ @Override
92
+ public void onViewAttachedToWindow(@NonNull PageViewHolder holder) {
93
+ super.onViewAttachedToWindow(holder);
94
+ removeAttachedViewKeys(holder.pageView);
95
+ int position = holder.getBindingAdapterPosition();
96
+ if (position == RecyclerView.NO_POSITION) {
97
+ return;
98
+ }
99
+ attachedViews.put(position, holder.pageView);
100
+ }
101
+
102
+ @Override
103
+ public void onViewDetachedFromWindow(@NonNull PageViewHolder holder) {
104
+ super.onViewDetachedFromWindow(holder);
105
+ removeAttachedViewKeys(holder.pageView);
106
+ }
107
+
108
+ @Override
109
+ public void onViewRecycled(@NonNull PageViewHolder holder) {
110
+ super.onViewRecycled(holder);
111
+ removeAttachedViewKeys(holder.pageView);
112
+ holder.pageView.release();
113
+ }
114
+
115
+ private void removeAttachedViewKeys(@NonNull NativeImagePreviewViewerPageView pageView) {
116
+ List<Integer> keys = new ArrayList<>();
117
+ for (Map.Entry<Integer, NativeImagePreviewViewerPageView> entry : attachedViews.entrySet()) {
118
+ if (entry.getValue() == pageView) {
119
+ keys.add(entry.getKey());
120
+ }
121
+ }
122
+ for (Integer key : keys) {
123
+ attachedViews.remove(key);
124
+ }
125
+ }
126
+
127
+ @Override
128
+ public int getItemCount() {
129
+ return items.size();
130
+ }
131
+
132
+ static final class PageViewHolder extends RecyclerView.ViewHolder {
133
+ final NativeImagePreviewViewerPageView pageView;
134
+
135
+ PageViewHolder(@NonNull NativeImagePreviewViewerPageView itemView) {
136
+ super(itemView);
137
+ this.pageView = itemView;
138
+ }
139
+ }
140
+ }
@@ -0,0 +1,25 @@
1
+ package cn.fontree.zkit.ui.preview;
2
+
3
+ import android.graphics.RectF;
4
+
5
+ import androidx.annotation.NonNull;
6
+
7
+ public final class NativeImagePreviewSharedElementGeometry {
8
+ private final RectF visibleFrameInWindow;
9
+ private final RectF contentFrameInVisibleBounds;
10
+
11
+ public NativeImagePreviewSharedElementGeometry(@NonNull RectF visibleFrameInWindow, @NonNull RectF contentFrameInVisibleBounds) {
12
+ this.visibleFrameInWindow = new RectF(visibleFrameInWindow);
13
+ this.contentFrameInVisibleBounds = new RectF(contentFrameInVisibleBounds);
14
+ }
15
+
16
+ @NonNull
17
+ public RectF getVisibleFrameInWindow() {
18
+ return new RectF(visibleFrameInWindow);
19
+ }
20
+
21
+ @NonNull
22
+ public RectF getContentFrameInVisibleBounds() {
23
+ return new RectF(contentFrameInVisibleBounds);
24
+ }
25
+ }
@@ -0,0 +1,39 @@
1
+ package cn.fontree.zkit.ui.preview;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import androidx.annotation.Nullable;
5
+
6
+ public final class NativeImagePreviewSharedElementNames {
7
+ private static final String PREFIX = "zkit-native-image-preview:media:";
8
+
9
+ private NativeImagePreviewSharedElementNames() {
10
+ }
11
+
12
+ @NonNull
13
+ public static String forItem(@NonNull NativeImagePreviewMediaItem item) {
14
+ return forItem(null, item);
15
+ }
16
+
17
+ @NonNull
18
+ public static String forItem(@Nullable String previewGroupId, @NonNull NativeImagePreviewMediaItem item) {
19
+ return forId(previewGroupId, item.getId());
20
+ }
21
+
22
+ @NonNull
23
+ public static String forIndex(int index) {
24
+ return forIndex(null, index);
25
+ }
26
+
27
+ @NonNull
28
+ public static String forIndex(@Nullable String previewGroupId, int index) {
29
+ return forId(previewGroupId, String.valueOf(index));
30
+ }
31
+
32
+ @NonNull
33
+ private static String forId(@Nullable String previewGroupId, @NonNull String id) {
34
+ if (previewGroupId == null || previewGroupId.isEmpty()) {
35
+ return PREFIX + id;
36
+ }
37
+ return PREFIX + previewGroupId + ":" + id;
38
+ }
39
+ }
@@ -0,0 +1,25 @@
1
+ package cn.fontree.zkit.ui.preview;
2
+
3
+ import android.graphics.drawable.Drawable;
4
+
5
+ import androidx.annotation.NonNull;
6
+
7
+ public final class NativeImagePreviewSharedElementState {
8
+ private final Drawable drawable;
9
+ private final NativeImagePreviewSharedElementGeometry geometry;
10
+
11
+ public NativeImagePreviewSharedElementState(@NonNull Drawable drawable, @NonNull NativeImagePreviewSharedElementGeometry geometry) {
12
+ this.drawable = drawable;
13
+ this.geometry = geometry;
14
+ }
15
+
16
+ @NonNull
17
+ public Drawable getDrawable() {
18
+ return drawable;
19
+ }
20
+
21
+ @NonNull
22
+ public NativeImagePreviewSharedElementGeometry getGeometry() {
23
+ return geometry;
24
+ }
25
+ }
@@ -0,0 +1,115 @@
1
+ package cn.fontree.zkit.ui.preview;
2
+
3
+ import android.view.View;
4
+ import android.widget.ImageView;
5
+
6
+ import androidx.annotation.NonNull;
7
+ import androidx.annotation.Nullable;
8
+ import androidx.core.view.ViewCompat;
9
+
10
+ import java.lang.ref.WeakReference;
11
+ import java.util.HashMap;
12
+ import java.util.Iterator;
13
+ import java.util.Map;
14
+
15
+ public final class NativeImagePreviewSourceViewRegistry {
16
+ private static final Map<String, WeakReference<ImageView>> SOURCE_VIEWS = new HashMap<>();
17
+
18
+ private NativeImagePreviewSourceViewRegistry() {
19
+ }
20
+
21
+ public static synchronized void register(@NonNull String key, @NonNull ImageView imageView) {
22
+ cleanupLocked();
23
+ if (!hasUsableGeometry(imageView)) {
24
+ ImageView existingImageView = resolveMappedViewLocked(key);
25
+ boolean keepExisting = existingImageView != null
26
+ && existingImageView != imageView
27
+ && hasUsableGeometry(existingImageView);
28
+ clearMappingsForViewLocked(imageView);
29
+ if (keepExisting) {
30
+ SOURCE_VIEWS.put(key, new WeakReference<>(existingImageView));
31
+ return;
32
+ }
33
+ SOURCE_VIEWS.remove(key);
34
+ return;
35
+ }
36
+
37
+ ImageView previousImageView = resolveMappedViewLocked(key);
38
+ if (!isPreferredSourceView(imageView)
39
+ && previousImageView != null
40
+ && previousImageView != imageView
41
+ && isPreferredSourceView(previousImageView)) {
42
+ clearMappingsForViewLocked(imageView);
43
+ SOURCE_VIEWS.put(key, new WeakReference<>(previousImageView));
44
+ return;
45
+ }
46
+
47
+ clearMappingsForViewLocked(imageView);
48
+ SOURCE_VIEWS.put(key, new WeakReference<>(imageView));
49
+ ViewCompat.setTransitionName(imageView, key);
50
+ }
51
+
52
+ public static synchronized void unregisterView(@NonNull ImageView imageView) {
53
+ clearMappingsForViewLocked(imageView);
54
+ }
55
+
56
+ @Nullable
57
+ public static synchronized ImageView find(@NonNull String key) {
58
+ cleanupLocked();
59
+ WeakReference<ImageView> reference = SOURCE_VIEWS.get(key);
60
+ if (reference == null) {
61
+ return null;
62
+ }
63
+ ImageView imageView = reference.get();
64
+ if (imageView == null || !imageView.isAttachedToWindow()) {
65
+ SOURCE_VIEWS.remove(key);
66
+ return null;
67
+ }
68
+ if (!hasUsableGeometry(imageView)) {
69
+ SOURCE_VIEWS.remove(key);
70
+ return null;
71
+ }
72
+ return imageView;
73
+ }
74
+
75
+ @Nullable
76
+ private static ImageView resolveMappedViewLocked(@NonNull String key) {
77
+ WeakReference<ImageView> reference = SOURCE_VIEWS.get(key);
78
+ return reference != null ? reference.get() : null;
79
+ }
80
+
81
+ private static boolean hasUsableGeometry(@Nullable ImageView imageView) {
82
+ return imageView != null
83
+ && imageView.isAttachedToWindow()
84
+ && imageView.getWidth() > 0
85
+ && imageView.getHeight() > 0;
86
+ }
87
+
88
+ private static boolean isPreferredSourceView(@Nullable ImageView imageView) {
89
+ return hasUsableGeometry(imageView)
90
+ && imageView.getVisibility() == View.VISIBLE
91
+ && imageView.isShown();
92
+ }
93
+
94
+ private static void clearMappingsForViewLocked(@NonNull ImageView imageView) {
95
+ Iterator<Map.Entry<String, WeakReference<ImageView>>> iterator = SOURCE_VIEWS.entrySet().iterator();
96
+ while (iterator.hasNext()) {
97
+ Map.Entry<String, WeakReference<ImageView>> entry = iterator.next();
98
+ ImageView mappedView = entry.getValue().get();
99
+ if (mappedView == null || mappedView == imageView) {
100
+ iterator.remove();
101
+ }
102
+ }
103
+ }
104
+
105
+ private static void cleanupLocked() {
106
+ Iterator<Map.Entry<String, WeakReference<ImageView>>> iterator = SOURCE_VIEWS.entrySet().iterator();
107
+ while (iterator.hasNext()) {
108
+ Map.Entry<String, WeakReference<ImageView>> entry = iterator.next();
109
+ ImageView mappedView = entry.getValue().get();
110
+ if (mappedView == null) {
111
+ iterator.remove();
112
+ }
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,60 @@
1
+ package cn.fontree.zkit.ui.preview;
2
+
3
+ import android.content.Context;
4
+ import android.graphics.RectF;
5
+ import android.graphics.drawable.Drawable;
6
+ import android.view.Gravity;
7
+ import android.widget.FrameLayout;
8
+ import android.widget.ImageView;
9
+
10
+ import androidx.annotation.NonNull;
11
+
12
+ public final class NativeImagePreviewTransitionSnapshotView extends FrameLayout {
13
+ private final ImageView imageView;
14
+
15
+ public NativeImagePreviewTransitionSnapshotView(@NonNull Context context, @NonNull Drawable drawable) {
16
+ super(context);
17
+ setClipChildren(true);
18
+ setClipToPadding(true);
19
+ imageView = new ImageView(context);
20
+ imageView.setScaleType(ImageView.ScaleType.FIT_XY);
21
+ imageView.setImageDrawable(drawable);
22
+ addView(imageView);
23
+ }
24
+
25
+ public void applyGeometry(@NonNull NativeImagePreviewSharedElementGeometry geometry) {
26
+ RectF visibleFrame = geometry.getVisibleFrameInWindow();
27
+ FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
28
+ if (layoutParams == null) {
29
+ layoutParams = new FrameLayout.LayoutParams(
30
+ Math.max(1, Math.round(visibleFrame.width())),
31
+ Math.max(1, Math.round(visibleFrame.height()))
32
+ );
33
+ }
34
+ layoutParams.width = Math.max(1, Math.round(visibleFrame.width()));
35
+ layoutParams.height = Math.max(1, Math.round(visibleFrame.height()));
36
+ layoutParams.leftMargin = 0;
37
+ layoutParams.topMargin = 0;
38
+ layoutParams.gravity = Gravity.TOP | Gravity.START;
39
+ setLayoutParams(layoutParams);
40
+ setX(visibleFrame.left);
41
+ setY(visibleFrame.top);
42
+
43
+ RectF contentFrame = geometry.getContentFrameInVisibleBounds();
44
+ FrameLayout.LayoutParams imageLayoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams();
45
+ if (imageLayoutParams == null) {
46
+ imageLayoutParams = new FrameLayout.LayoutParams(
47
+ Math.max(1, Math.round(contentFrame.width())),
48
+ Math.max(1, Math.round(contentFrame.height()))
49
+ );
50
+ }
51
+ imageLayoutParams.width = Math.max(1, Math.round(contentFrame.width()));
52
+ imageLayoutParams.height = Math.max(1, Math.round(contentFrame.height()));
53
+ imageLayoutParams.leftMargin = 0;
54
+ imageLayoutParams.topMargin = 0;
55
+ imageLayoutParams.gravity = Gravity.TOP | Gravity.START;
56
+ imageView.setLayoutParams(imageLayoutParams);
57
+ imageView.setX(contentFrame.left);
58
+ imageView.setY(contentFrame.top);
59
+ }
60
+ }