Amrmsmb
Amrmsmb

Reputation: 11416

How to get the total number of Views in a lyout including subviews

I am trying to count all the views in any layout being displayed to the user. To achieve it, the code posted below was used, but as you see in the layout, it contains

    Button
    LinearLayout
        Button
        Button
    TextView
    LinearLayout

when the code is executed, it says that the layout has only 4 widgets "Button, LinearLayout, TextView, LinearLayout", while I expected the code to return 6 widgets. would you please tell me how to get the total widgets contains in a layout including the sub-widgets/views?

code:

public class ActMain extends AppCompatActivity {

private static final String TAG = ActMain.class.getSimpleName();
private LinearLayout mMainContainer = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.act_main);

    this.mMainContainer = (LinearLayout) findViewById(R.id.actMain_mainContainer);
    int totalWidgets = this.mMainContainer.getChildCount();
    Log.d(TAG, "totalWidgets:" + totalWidgets);


    for (int i = 0; i < this.mMainContainer.getChildCount(); i++) {
        View view = mMainContainer.getChildAt(i);
    }
}

}

layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/actMain_mainContainer"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.alten.test_traversethroughaview_1.ActMain">

    <Button
        android:id="@+id/actMain_btn_change"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/decision_change" />

        <LinearLayout
            android:id="@+id/actMain_linlay_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/actMain_btn_yes"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/decision_yes" />
            <Button
                android:id="@+id/actMain_btn_no"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/decision_no" />
        </LinearLayout>

        <TextView
            android:id="@+id/actMain_tv_display"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <LinearLayout
            android:id="@+id/actMain_linlay_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
        </LinearLayout>

Upvotes: 3

Views: 2986

Answers (3)

Haniyeh Khaksar
Haniyeh Khaksar

Reputation: 804

use this method:

public int getChildrenViews(ViewGroup parent){
    int count = parent.getChildCount();
    for (int i=0;i<parent.getChildCount();i++){
        if (parent.getChildAt(i) instanceof ViewGroup){
            count+=getChildrenViews((ViewGroup) parent.getChildAt(i));
        }
    }
    return count;
}

anywhere you want add this part:

if (getWindow().getDecorView().getRootView() instanceof ViewGroup){
        getChildrenViews((ViewGroup) getWindow().getDecorView().getRootView());
    }

Upvotes: 2

Abu Yousuf
Abu Yousuf

Reputation: 6107

Your code only counting its parent child, not all the child in the layout. That means you are counting Grandfather's child not Grandfather's Grandchild. You have to traverse all view to count all child. To do that you can use a recursive function to count all child.

getChildCount(View)
  count = 1;
  check the view is instance of ViewGroup
  if it is ViewGroup 
    for each child 
      count+= getChildCount(child)

  return count

Call this with root layout

totalChild = getChildCount(root)

Hope you can count all child this way.

Upvotes: 0

Pado
Pado

Reputation: 1637

This function will probably help:

private int countChild(View view) {
    if (!(view instanceof ViewGroup))
        return 1;

    int counter = 0;

    ViewGroup viewGroup = (ViewGroup) view;

    for (int i=0; i<viewGroup.getChildCount(); i++) {
        counter += countChild(viewGroup.getChildAt(i));
    }

    return counter;
}

It only counts the leaves (ignores the ViewGroups). But if you want to count also them if is straightforward: just substitute counter = 0 with counter = 1.

Upvotes: 0

Related Questions