-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathViewUtils.java
More file actions
127 lines (104 loc) · 4.23 KB
/
ViewUtils.java
File metadata and controls
127 lines (104 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.reactnativenavigation.utils;
import android.graphics.Point;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
import static com.reactnativenavigation.utils.ObjectUtils.perform;
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable;
public class ViewUtils {
@Nullable
public static <T extends View> T findChildByClass(ViewGroup root, Class<T> clazz) {
for (int i = 0; i < root.getChildCount(); i++) {
View view = root.getChildAt(i);
if (clazz.isAssignableFrom(view.getClass())) {
return (T) view;
}
if (view instanceof ViewGroup) {
view = findChildByClass((ViewGroup) view, clazz);
if (view != null && clazz.isAssignableFrom(view.getClass())) {
return (T) view;
}
}
}
return null;
}
public static <T> List<T> findChildrenByClassRecursive(ViewGroup root, Class<?> clazz) {
return findChildrenByClassRecursive(root, clazz, child -> true);
}
public static <T> List<T> findChildrenByClassRecursive(ViewGroup root, Class<?> clazz, Matcher<T> matcher) {
ArrayList<T> ret = new ArrayList<>();
for (int i = 0; i < root.getChildCount(); i++) {
View view = root.getChildAt(i);
if (view instanceof ViewGroup) {
ret.addAll(findChildrenByClassRecursive((ViewGroup) view, clazz, matcher));
}
if (clazz.isAssignableFrom(view.getClass()) && matcher.match((T) view)) {
ret.add((T) view);
}
}
return ret;
}
public static <T> List<T> findChildrenByClass(ViewGroup root, Class<T> clazz) {
return findChildrenByClass(root, clazz, child -> true);
}
public static <T> List<T> findChildrenByClass(ViewGroup root, Class<?> clazz, Matcher<T> matcher) {
List<T> ret = new ArrayList<>();
for (int i = 0; i < root.getChildCount(); i++) {
View child = root.getChildAt(i);
if (clazz.isAssignableFrom(child.getClass()) && matcher.match((T) child)) {
ret.add((T) child);
}
}
return ret;
}
public interface Matcher<T> {
boolean match(T child);
}
public static boolean isChildOf(ViewGroup parent, View child) {
if (parent == child) return false;
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
if (view == child) {
return true;
}
if (view instanceof ViewGroup) {
if (isChildOf((ViewGroup) view, child)) return true;
}
}
return false;
}
public static int getHeight(View view) {
if (view.getLayoutParams() == null) return 0;
return view.getLayoutParams().height < 0 ? view.getHeight() : view.getLayoutParams().height;
}
public static Point getLocationOnScreen(View view) {
int[] xy = new int[2];
view.getLocationOnScreen(xy);
return new Point(xy[0], xy[1]);
}
public static boolean areDimensionsEqual(View a, View b) {
return a.getWidth() == b.getWidth() && a.getHeight() == b.getHeight();
}
public static int getIndexInParent(View view) {
ViewParent parent = view.getParent();
if (parent == null) return -1;
return ((ViewGroup) parent).indexOfChild(view);
}
@UnstableReactNativeAPI
public static int getBackgroundColor(View view) {
if (view.getBackground() instanceof CSSBackgroundDrawable) {
return ((CSSBackgroundDrawable) view.getBackground()).getColor();
}
throw new RuntimeException(view.getBackground().getClass().getSimpleName() + " is not ReactViewBackgroundDrawable");
}
public static boolean isVisible(View view) {
return perform(view, false, v -> v.getVisibility() == View.VISIBLE);
}
public static int topMargin(View view) {
return ((ViewGroup.MarginLayoutParams) view.getLayoutParams()).topMargin;
}
}