Android - 让孩子进入视图?

ary*_*axt 160 android view

给定一个视图如何在其中获取子视图?

所以我有一个自定义View和调试器显示mChildren其他7个视图.我需要一种方法来访问这些视图,但似乎没有公共API来执行此操作.

有什么建议?

编辑:

我的自定义视图继承自 AdapterView

Ale*_*tin 298

for(int index=0; index<((ViewGroup)viewGroup).getChildCount(); ++index) {
    View nextChild = ((ViewGroup)viewGroup).getChildAt(index);
}
Run Code Online (Sandbox Code Playgroud)

那会吗?

  • 以递归方式执行此操作的最佳方法是什么,从而生成视图层次结构JSON对象? (2认同)

IHe*_*oid 56

如果你不仅想要所有直接的孩子,而是所有孩子的孩子等等,你必须递归地做:

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;
}
Run Code Online (Sandbox Code Playgroud)

要使用结果,您可以执行以下操作:

    // 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");
    }
Run Code Online (Sandbox Code Playgroud)

  • 此调用不是保存,例如,child可以是View类型而不是ViewGroup类型,因此getAllChildren的递归调用可能会导致异常,因为转换失败.所以你应该添加一个if(!(v instanceof ViewGroup))return; 演员之前 (7认同)
  • 小建议:用`for(int i = 0,n = vg.getChildCount(); i <n; i ++)替换你的for循环.在Android上,访问局部变量而不是调用方法往往要快得多.这样,每个视图组只调用一次方法,然后在后续运行中使用局部变量. (2认同)

小智 17

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

例如,在活动/视图中:

...
private void init() {
  View child1 = findViewById(R.id.child1);
}
...
Run Code Online (Sandbox Code Playgroud)

或者如果您有对视图的引用:

...
private void init(View root) {
  View child2 = root.findViewById(R.id.child2);
}
Run Code Online (Sandbox Code Playgroud)


MH.*_*MH. 16

我将提供这个答案作为替代@ IHeartAndroid的递归算法,用于发现View视图层次结构中的所有子项.请注意,在撰写本文时,递归解决方案存在缺陷,因为它将在结果中包含重复项.

对于那些在递归时遇到麻烦的人来说,这是一个非递归的替代方案.你可以获得奖励积分,这也是一种广泛优先的搜索替代递归解决方案的深度优先方法.

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;
}
Run Code Online (Sandbox Code Playgroud)

一些快速测试(没有正式的)表明这种替代方案也更快,尽管这很可能与ArrayList另一个答案创建的新实例的数量有关.此外,结果可能会根据视图层次结构的垂直/水平方式而有所不同.

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


van*_*lov 5

这是一个建议:您可以通过使用其给定名称(例如)获得ID(例如,通过android:id="@+id/..My Str..)生成的.然后,使用方法的代码片段将是:RMy StrgetIdentifier()

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;
}
Run Code Online (Sandbox Code Playgroud)

从一个内部 Activity,一个示例用法与findViewById:

// Get the View (e.g. a TextView) which has the Layout ID of "UserInput"
int rID = getIdAssignedByR(this, "UserInput")
TextView userTextView = (TextView) findViewById(rID);
Run Code Online (Sandbox Code Playgroud)