Android - 如何使用common属性查找多个视图

Shl*_*rtz 33 android view

我有一个多个ImageViews 的布局,其中一些图像需要具有相同的onClickListener.我希望我的代码具有灵活性,能够获得这些代码的集合,View在运行时迭代并添加监听器.

有没有像findViewById这样的方法会返回一个Views而不是一个s 的集合?

Shl*_*rtz 54

我终于写了这个方法(更新感谢@SuitUp(校正的用户名)):

private static ArrayList<View> getViewsByTag(ViewGroup root, String tag){
    ArrayList<View> views = new ArrayList<View>();
    final int childCount = root.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = root.getChildAt(i);
        if (child instanceof ViewGroup) {
            views.addAll(getViewsByTag((ViewGroup) child, tag));
        } 

        final Object tagObj = child.getTag();
        if (tagObj != null && tagObj.equals(tag)) {
            views.add(child);
        }

    }
    return views;
}
Run Code Online (Sandbox Code Playgroud)

它将返回具有android:tag="TAG_NAME"属性的所有视图.请享用 ;)

  • 您可以使用Objects.equal(tagObj,tag)来获得更清晰的代码,还可以查询没有标记的视图.您还可以通过让tag参数成为对象来使方法更通用,因为标记可能不是字符串.(并返回List <View>或Collection <View>将是更好的做法). (4认同)
  • 太棒了,+ 1.我创建了一个变体,它返回根视图,如果它有标记.https://gist.github.com/orip/5566666 (4认同)

Sui*_*tUp 17

Shlomi Schwartz的方法有一个缺陷,它不收集Viewswchich ViewGroups.这是我的修复:

private static ArrayList<View> getViewsByTag(ViewGroup root, String tag){
    ArrayList<View> views = new ArrayList<View>();
    final int childCount = root.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = root.getChildAt(i);
        if (child instanceof ViewGroup) {
            views.addAll(getViewsByTag((ViewGroup) child, tag));
        } 

        final Object tagObj = child.getTag();
        if (tagObj != null && tagObj.equals(tag)) {
            views.add(child);
        }

    }
    return views;
}
Run Code Online (Sandbox Code Playgroud)


jus*_*mer 6

findViewById没有返回一组视图的方法,但您可以迭代视图并将它们设置为onClickListener,如下所示:

for (int i = 0;i < layout.getChildCount();i++) {
  View child = layout.getChildAt(i);
  //you can check for view tag or something to see if it satisfies your criteria
  //child.setOnClickListener...
}
Run Code Online (Sandbox Code Playgroud)

UPD: 对于递归视图层次结构(这是来自真实项目的示例,我们以递归方式查看刷新,但您可以使用嵌套视图执行任何操作):

private void recursiveViewRefresh(ViewGroup view) {
    for (int i = 0;i < view.getChildCount();i++) {
        View child = view.getChildAt(i);
        try {
            ViewGroup viewGroup = (ViewGroup) child;
            recursiveViewRefresh(viewGroup);
        } catch (ClassCastException e) {
            //just ignore the exception - it is used as a check
        }
        singleViewRefresh(child);
    }
}
Run Code Online (Sandbox Code Playgroud)