web-dev-qa-db-fra.com

Android - placez les enfants dans une vue?

Étant donné une vue, comment puis-je obtenir les vues d'enfants à l'intérieur?

J'ai donc une vue personnalisée et le débogueur montre que sous mChildren, il y a 7 autres vues. J'ai besoin d'un moyen d'accéder à ces vues, mais il ne semble pas qu'il existe une API publique pour le faire.

aucune suggestion?

EDIT:

Ma vue personnalisée hérite de AdapterView

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

Cela fera-t-il?

290

Si vous voulez non seulement obtenir tous les enfants directs, mais également tous les enfants d'enfants, vous devez le faire de manière récursive:

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;
}

Pour utiliser le résultat, vous pouvez faire quelque chose comme ceci:

    // 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");
    }
55
IHeartAndroid

Vous pouvez toujours accéder aux vues enfant via View.findViewById () http://developer.Android.com/reference/Android/view/View.html#findViewById (int ).

Par exemple, dans une activité/vue:

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

ou si vous avez une référence à une vue:

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

Je vais simplement fournir cette réponse comme alternative à l'algorithme récursif de IHeartAndroid pour découvrir tous les enfants Views dans une hiérarchie de vues. Notez qu'au moment où nous écrivons, la solution récursive est défectueuse dans la mesure où elle contiendra des doublons dans son résultat.

Pour ceux qui ont du mal à comprendre la récursion, voici une alternative non récursive. Vous obtenez des points bonus si vous réalisez que c'est également une alternative de recherche width-first à l'approche depth-first de la solution récursive.

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;
}

Quelques tests rapides (rien de formel) suggèrent que cette alternative est également plus rapide, bien que cela ait probablement plus à voir avec le nombre de nouvelles instances ArrayList créées par l'autre réponse. En outre, les résultats peuvent varier en fonction de la hiérarchie verticale/horizontale de la vue.

Transféré depuis: Android | Obtenir tous les éléments enfants d'un ViewGroup

15
MH.

Voici une suggestion: vous pouvez obtenir la ID (spécifiée par exemple par Android:id="@+id/..My Str..) qui a été générée par R à l’aide de son nom (par exemple My Str). Un extrait de code utilisant la méthode getIdentifier() serait alors:

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;
}

À l'intérieur de Activity, un exemple d'utilisation associé à findViewById serait:

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

Afin d'actualiser une disposition de table (TableLayout), j'ai finalement dû utiliser l'approche récursive mentionnée ci-dessus pour obtenir tous les enfants des enfants, etc.

Ma situation était quelque peu simplifiée parce que je n'avais besoin que de travailler avec LinearLayout et que les classes étendues à partir de celle-ci, telles que TableLayout. Et je n'étais intéressé que par la recherche d'enfants TextView. Mais je pense que cela reste applicable à cette question.

La classe finale s'exécute en tant que thread séparé, ce qui signifie qu'elle peut effectuer d'autres tâches en arrière-plan avant d'analyser les enfants. Le code est petit et simple et peut être trouvé à github: https://github.com/jkincali/Android-LinearLayout-Parser

0
jkincali