我正在为Android制作游戏。为了帮助实现它,我的想法是创建一个视图的子类。然后,我会将几个此类的实例作为主视图的子级插入其中。每个实例都会通过OnTouchListener检测何时被按下。
我现在遇到的问题是如何循环遍历所有这些子视图,以便读取它们的状态并处理它们?(即当它们都达到某种状态时应该发生什么)。
或者,有没有更好的方法可以在屏幕上拥有多个响应触摸且可以检查其状态的对象?
我正在为Android制作游戏。为了帮助实现它,我的想法是创建一个视图的子类。然后,我会将几个此类的实例作为主视图的子级插入其中。每个实例都会通过OnTouchListener检测何时被按下。
我现在遇到的问题是如何循环遍历所有这些子视图,以便读取它们的状态并处理它们?(即当它们都达到某种状态时应该发生什么)。
或者,有没有更好的方法可以在屏幕上拥有多个响应触摸且可以检查其状态的对象?
我已经编写了一个递归函数的小例子:
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
,则重启该函数以检索该子项内的所有嵌套视图。
@jqpubliq 是正确的,但如果你真的想要遍历所有视图,你可以简单地使用ViewGroup
的getChildCount()
和getChildAt()
方法。一个简单的递归方法就可以完成其余部分。
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;
}
//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)
}
}
//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))
}
}
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;
}
使用Views
似乎会非常困难,如果有动态效果的话,渲染可能不会很好。除非你正在做一些非常静态的事情,否则你可能想要绘制到Canvas
或使用OpenGL
。这里有一个来自去年I/O大会的精彩演讲,讲述如何制作Android游戏。它有点长,你可以跳过前15分钟。此外,源代码也是可用的。这应该能给你提供一些关于如何处理事情的好主意。
for (int i = parent.getChildCount() - 1; i >= 0; i--)
而不是for (int i = 0; i < parent.getChildCount(); i++)
,有什么特别的原因吗? - Peter Prokopif (child instanceof ViewGroup)
之前添加if (child instanceof WebView)
条件。 - MewX