循环遍历 Android 视图的所有子视图?

发布于 2024-08-28 06:07:14 字数 225 浏览 13 评论 0原文

我正在开发一款 Android 游戏。为了帮助实现它,我的想法是创建视图的子类。然后,我将插入此类的几个实例作为主视图的子视图。每个实例都会处理按下时的检测(通过 OnTouchListener)。

我现在遇到的问题是如何循环遍历所有这些子视图,以便我可以读取它们的状态并处理它们? (即当它们都达到某种状态时,就会发生一些事情)。

或者是否有更好的方法让屏幕上有多个响应触摸的对象并且我可以检查其状态?

I’m working on a game for Android. To help implement it, my idea is to create a subclass of a view. I would then insert several instances of this class as children of the main view. Each instance would handle detecting when it was pressed (via OnTouchListener).

The problem I’m having now is how do I loop through all these sub-views so I can read their statuses and process them? (I.e. when they all reach a certain state something should happen).

Or is there a better way to have several objects on the screen that respond to touch and whose status I can check?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情绪失控 2024-09-04 06:07:14

我做了一个递归函数的小例子:

public void recursiveLoopChildren(ViewGroup parent) {
        for (int i = 0; i < parent.getChildCount(); i++) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                recursiveLoopChildren((ViewGroup) child);
                // DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED
            } else {
                if (child != null) {
                    // DO SOMETHING WITH VIEW
                }
            }
        }
    }

如果子元素是一个 ViewGroup,该函数将开始循环 ViewGroup 内的所有视图元素(从第一个到最后一个项目) > 然后使用该子项重新启动该函数以检索该子项内的所有嵌套视图。

I have made a small example of a recursive function:

public void recursiveLoopChildren(ViewGroup parent) {
        for (int i = 0; i < parent.getChildCount(); i++) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                recursiveLoopChildren((ViewGroup) child);
                // DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED
            } else {
                if (child != null) {
                    // DO SOMETHING WITH VIEW
                }
            }
        }
    }

The function will start looping over al view elements inside a ViewGroup (from first to last item), if a child is a ViewGroup then restart the function with that child to retrieve all nested views inside that child.

听你说爱我 2024-09-04 06:07:14

@jqpubliq 是对的,但如果你真的想浏览所有视图,你可以简单地使用 ViewGroup 中的 getChildCount()getChildAt() 方法。一个简单的递归方法将完成剩下的工作。

@jqpubliq Is right but if you really want to go through all Views you can simply use the getChildCount() and getChildAt() methods from ViewGroup. A simple recursive method will do the rest.

要走就滚别墨迹 2024-09-04 06:07:14

Android 循环遍历所有视图

另一种方法

public static void recursivelyFindChildren(View view) {
    if (view instanceof ViewGroup) {
        //ViewGroup
        ViewGroup viewGroup = (ViewGroup)view;
        
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            recursivelyFindChildren(viewGroup.getChildAt(i));
        }

    } else {
        //View
    }

}

或者您可以返回可以使用下一种方法的内容

@Nullable
private static WebView recursivelyFindWebView(View view) {
    if (view instanceof ViewGroup) {
        //ViewGroup
        ViewGroup viewGroup = (ViewGroup)view;

        if (!(viewGroup instanceof WebView)) {
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                WebView result = recursivelyFindWebView(viewGroup.getChildAt(i));

                if (result != null) {
                    return result;
                }
            }
        } else {
            //WebView

            WebView webView = (WebView)viewGroup;
            return webView;
        }
    }
    return null;
}

Android loop through all views

The alternative

public static void recursivelyFindChildren(View view) {
    if (view instanceof ViewGroup) {
        //ViewGroup
        ViewGroup viewGroup = (ViewGroup)view;
        
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            recursivelyFindChildren(viewGroup.getChildAt(i));
        }

    } else {
        //View
    }

}

Or you can return something you can use the next approach

@Nullable
private static WebView recursivelyFindWebView(View view) {
    if (view instanceof ViewGroup) {
        //ViewGroup
        ViewGroup viewGroup = (ViewGroup)view;

        if (!(viewGroup instanceof WebView)) {
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                WebView result = recursivelyFindWebView(viewGroup.getChildAt(i));

                if (result != null) {
                    return result;
                }
            }
        } else {
            //WebView

            WebView webView = (WebView)viewGroup;
            return webView;
        }
    }
    return null;
}
咽泪装欢 2024-09-04 06:07:14

在 Kotlin 中,我在 ViewGroup 上使用扩展函数:

//call forOneChild for the ViewGroup itself, and all sub Views/ViewGroups
fun ViewGroup.forAllChildren(forOneChild: (v: View) -> Unit) {
    forOneChild(this)
    for (cx in 0 until childCount) {
        val child = getChildAt(cx)
        if (child is ViewGroup)
            child.forAllChildren(forOneChild)
        else
            forOneChild(child)
    }
}

然后我可以调用它(对于任何 ViewGroup,从任何地方)。

例子:

        //set colors for sub views
        val colorHi = Color.parseColor("#006400") //DarkGreen
        val colorLo = Color.parseColor("#90EE90") //LightGreen

        binding.root.forAllChildren { v ->
            when (v) {
                is CheckBox -> v.buttonTintList = ColorStateList.valueOf(colorHi)
                is Spinner -> v.setPopupBackgroundDrawable(ColorDrawable(colorLo))
            }
        }

In Kotlin, I am using an extension function on ViewGroup:

//call forOneChild for the ViewGroup itself, and all sub Views/ViewGroups
fun ViewGroup.forAllChildren(forOneChild: (v: View) -> Unit) {
    forOneChild(this)
    for (cx in 0 until childCount) {
        val child = getChildAt(cx)
        if (child is ViewGroup)
            child.forAllChildren(forOneChild)
        else
            forOneChild(child)
    }
}

I can then call this (for any ViewGroup, from anywhere).

Example:

        //set colors for sub views
        val colorHi = Color.parseColor("#006400") //DarkGreen
        val colorLo = Color.parseColor("#90EE90") //LightGreen

        binding.root.forAllChildren { v ->
            when (v) {
                is CheckBox -> v.buttonTintList = ColorStateList.valueOf(colorHi)
                is Spinner -> v.setPopupBackgroundDrawable(ColorDrawable(colorLo))
            }
        }
杯别 2024-09-04 06:07:14

试试这个。获取父布局内的所有视图返回视图的数组列表。

public List<View> getAllViews(ViewGroup layout){
        List<View> views = new ArrayList<>();
        for(int i =0; i< layout.getChildCount(); i++){
            views.add(layout.getChildAt(i));
        }
        return views;
    }

Try this. Takes all views inside a parent layout & returns an array list of views.

public List<View> getAllViews(ViewGroup layout){
        List<View> views = new ArrayList<>();
        for(int i =0; i< layout.getChildCount(); i++){
            views.add(layout.getChildAt(i));
        }
        return views;
    }
ペ泪落弦音 2024-09-04 06:07:14

使用 Views 听起来如果有运动的话,渲染任何东西都会变得非常困难。您可能想要绘制到 Canvas 或使用 OpenGL 除非您正在做一些真正静态的事情。这是去年 I/O 大会上的精彩演讲制作安卓游戏。它有点长,你可以跳过大约 15 分钟。而且源代码也可用。这应该能让你了解处理事情的方法

Using Views sounds like its going to be brutally difficult to render anything well if there is movement. You probably want to be drawing to a Canvas or using OpenGL unless you're doing something really static. Here's a great talk from last years I/O conference on making Android games. Its kind of long and you can skip about 15 minutes in. Also the source is available. That should give you a good idea of ways to go about things

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文