I am making SKD for Automation. So my needs are slightly different that normal app development.
Requirement: Get ViewHierarchy of current activity. Problem: I get it correct when Spinner is not open. I do not get the details of spinner when its open.
I use following code to get hierarchy. Questions is: Does Spinner get hosted in a different window which is why I am not getting it? What would be the way to get it?
//This is how I start recursion to get view hierarchy
View view = getWindow().getDecorView().getRootView();
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
dumpViewHierarchyWithProperties( group, 0);
}
//Functions to get hierarchy
private void dumpViewHierarchyWithProperties(ViewGroup group,int level) {
if (!dumpViewWithProperties(group, level)) {
return;
}
final int count = group.getChildCount();
for (int i = 0; i < count; i++) {
final View view = group.getChildAt(i);
if (view instanceof ViewGroup) {
dumpViewHierarchyWithProperties((ViewGroup) view, level + 1);
} else {
dumpViewWithProperties(view, level + 1);
}
}
}
private boolean dumpViewWithProperties(View view,int level) {
//Add to view Hierarchy.
return true;
}
I have managed to get the opened spinner popup view hierarchy using part of your code in addition to some other reflection magic, here is the full code, take in mind that reflection will affect the performance of your SDK and the applications that use it.
//Function to get all available windows of the application using reflection
private void logRootViews() {
try {
Class wmgClass = Class.forName("android.view.WindowManagerGlobal");
Object wmgInstnace = wmgClass.getMethod("getInstance").invoke(null, (Object[])null);
Method getViewRootNames = wmgClass.getMethod("getViewRootNames");
Method getRootView = wmgClass.getMethod("getRootView", String.class);
String[] rootViewNames = (String[])getViewRootNames.invoke(wmgInstnace, (Object[])null);
for(String viewName : rootViewNames) {
View rootView = (View)getRootView.invoke(wmgInstnace, viewName);
Log.i(TAG, "Found root view: " + viewName + ": " + rootView);
getViewHierarchy(rootView);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//Functions to get hierarchy
private void getViewHierarchy(View view) {
//This is how I start recursion to get view hierarchy
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
dumpViewHierarchyWithProperties(group, 0);
} else {
dumpViewWithProperties(view, 0);
}
}
private void dumpViewHierarchyWithProperties(ViewGroup group, int level) {
if (!dumpViewWithProperties(group, level)) {
return;
}
final int count = group.getChildCount();
for (int i = 0; i < count; i++) {
final View view = group.getChildAt(i);
if (view instanceof ViewGroup) {
dumpViewHierarchyWithProperties((ViewGroup) view, level + 1);
} else {
dumpViewWithProperties(view, level + 1);
}
}
}
private boolean dumpViewWithProperties(View view, int level) {
//Add to view Hierarchy.
if (view instanceof TextView) {
Log.d(TAG, "TextView from hierarchy dumped: " + view.toString() + " with text: " + ((TextView) view).getText().toString() + " ,in Level: " + level);
} else {
Log.d(TAG, "View from hierarchy dumped: " + view.toString() + " ,in Level: " + level);
}
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With