Android – 让孩子在视图内?

鉴于一个View如何获得它里面的子视图?

所以我有一个自定义的视图和debugging器显示,在mChildren下还有7个其他视图。 我需要一种方法来访问这些意见,但似乎并没有一个公共的API来做到这一点。

有什么build议么?

编辑:

我的自定义视图inheritance自AdapterView

 for(int index=0; index<((ViewGroup)viewGroup).getChildCount(); ++index) { View nextChild = ((ViewGroup)viewGroup).getChildAt(index); } 

会这样吗?

如果你不仅要得到所有直接的孩子,而且要得到所有的孩子的孩子等等,你必须recursion地做:

 private ArrayList<View> getAllChildren(View v) { if (!(v instanceof ViewGroup)) { ArrayList<View> viewArrayList = new ArrayList<View>(); viewArrayList.add(v); return viewArrayList; } ArrayList<View> result = new ArrayList<View>(); ViewGroup vg = (ViewGroup) v; for (int i = 0; i < vg.getChildCount(); i++) { View child = vg.getChildAt(i); ArrayList<View> viewArrayList = new ArrayList<View>(); viewArrayList.add(v); viewArrayList.addAll(getAllChildren(child)); result.addAll(viewArrayList); } return result; } 

要使用结果,你可以做这样的事情:

  // check if a child is set to a specific String View myTopView; String toSearchFor = "Search me"; boolean found = false; ArrayList<View> allViewsWithinMyTopView = getAllChildren(myTopView); for (View child : allViewsWithinMyTopView) { if (child instanceof TextView) { TextView childTextView = (TextView) child; if (TextUtils.equals(childTextView.getText().toString(), toSearchFor)) { found = true; } } } if (!found) { fail("Text '" + toSearchFor + "' not found within TopView"); } 

您可以随时通过View.findViewById() http://developer.android.com/reference/android/view/View.html#findViewById (int)访问子视图。

例如,在一个activity / view中:

 ... private void init() { View child1 = findViewById(R.id.child1); } ... 

或者如果你有一个视图的引用:

 ... private void init(View root) { View child2 = root.findViewById(R.id.child2); } 

我只是想提供这个答案作为替代@ IHeartAndroid的recursionalgorithm来发现视图层次结构中的所有子View 。 请注意,在撰写本文时, recursion解决scheme存在缺陷 ,因为它的结果中包含重复项。

对于那些无法绕开recursion的人来说,这是一个非recursion的select。 您可以获得奖励积分,这也是recursion解决scheme的深度优先方法的广度优先search替代scheme。

 private List<View> getAllChildrenBFS(View v) { List<View> visited = new ArrayList<View>(); List<View> unvisited = new ArrayList<View>(); unvisited.add(v); while (!unvisited.isEmpty()) { View child = unvisited.remove(0); visited.add(child); if (!(child instanceof ViewGroup)) continue; ViewGroup group = (ViewGroup) child; final int childCount = group.getChildCount(); for (int i=0; i<childCount; i++) unvisited.add(group.getChildAt(i)); } return visited; } 

几个快速testing(没有任何forms的)表明这个select也更快,尽pipe这最有可能与其他答案创build的新ArrayList实例的数量有关。 此外,结果可能会根据视图层次结构的垂直/水平方式而有所不同。

交叉发布: Android | 获取ViewGroup的所有子元素

这里有一个build议:你可以通过使用它的名字(例如My Str )来获得由R生成的ID (例如由android:id="@+id/..My Str..指定)。 getIdentifier()方法将是:

 public int getIdAssignedByR(Context pContext, String pIdString) { // Get the Context's Resources and Package Name Resources resources = pContext.getResources(); String packageName = pContext.getPackageName(); // Determine the result and return it int result = resources.getIdentifier(pIdString, "id", packageName); return result; } 

在一个Activity ,一个与findViewById结合使用的例子是:

 // Get the View (eg a TextView) which has the Layout ID of "UserInput" int rID = getIdAssignedByR(this, "UserInput") TextView userTextView = (TextView) findViewById(rID); 

为了刷新表格布局(TableLayout),我最后不得不使用上面提到的recursion方法来获取所有孩子的孩子等等。

我的情况有所简化,因为我只需要使用LinearLayout和从它扩展的类,如TableLayout。 而且我只对findTextView儿童感兴趣。 但是我认为这个问题仍然适用。

最后一个类作为一个单独的线程运行,这意味着它可以在为子节点parsing之前在后台执行其他操作。 代码很小,很简单,可以在github上find: https : //github.com/jkincali/Android-LinearLayout-Parser