Android中View的遍历

原文http://android-wtf.com/2013/06/how-to-easily-traverse-any-view-hierarchy-in-android/

翻墙看的一篇文章,直接复制过来了,懒得翻译了吐舌头

Have you ever wanted to find all the views marked with a specific tag? Well, the Android SDK only allows to find the first one. How about finding a specific type of views?

Faced with this very problem, I had to write a couple of utility classes, and now I’m sharing it. Before the library code I’ll show a demonstration of its usage. Here’s how you can traverse the whole view hierarchy of your Activity:

ViewGroup root = (ViewGroup) findViewById(android.R.id.content);

LayoutTraverser.build(new LayoutTraverser.Processor() {
  @Override
  public void process(View view) {
    // do stuff with the view
  }
}).traverse(root);

You can pass any ViewGroup instance (such LinearLayoutRelativeLayout and FrameLayout) to the traverse method, and for every view under the hierarchy (including the root ViewGroupitself) the process method will be executed.

If you want to traverse multiple hierarchies using the same processing logic:

LayoutTraverser traverser = LayoutTraverser.build(new LayoutTraverser.Processor() {
  @Override
  public void process(View view) {
    // do stuff with the view
  }
});

traverser.traverse(root);
traverser.traverse(root2);
traverser.traverse(root3);

There are two static methods included which I believe cover the majority of use-cases: finding views by tag and finding views of a specific type:

// all views tagged "coolView" under "root"
List<View> coolViews = Views.find(root, "coolView");

// all ImageView views under "root"
List<ImageView> imageViews = Views.find(root, ImageView.class);

The LayoutTraverser class:

package com.androidwtf.android;

import android.view.View;
import android.view.ViewGroup;

public class LayoutTraverser {
  public interface Processor {
    void process(View view);
  }

  private final Processor processor;

  private LayoutTraverser(Processor processor) {
    this.processor = processor;
  }

  public static LayoutTraverser build(Processor processor) {
    return new LayoutTraverser(processor);
  }

  public void traverse(ViewGroup root) {
    final int childCount = root.getChildCount();

    for (int i = 0; i < childCount; ++i) {
      final View child = root.getChildAt(i);
      processor.process(child);

      if (child instanceof ViewGroup) {
        traverse((ViewGroup) child);
      }
    }
  }
}

The Views class:

package com.androidwtf.android;

import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

final public class Views {
  private Views() {}

  public static List<View> find(ViewGroup root, Object tag) {
    FinderByTag finderByTag = new FinderByTag(tag);
    LayoutTraverser.build(finderByTag).traverse(root);
    return finderByTag.getViews();
  }

  public static <T extends View> List<T> find(ViewGroup root, Class<T> type) {
    FinderByType<T> finderByType = new FinderByType<T>(type);
    LayoutTraverser.build(finderByType).traverse(root);
    return finderByType.getViews();
  }

  private static class FinderByTag implements LayoutTraverser.Processor {
    private final Object searchTag;
    private final List<View> views = new ArrayList<View>();

    private FinderByTag(Object searchTag) {
      this.searchTag = searchTag;
    }

    @Override
    public void process(View view) {
      Object viewTag = view.getTag();

      if (viewTag != null && viewTag.equals(searchTag)) {
        views.add(view);
      }
    }

    private List<View> getViews() {
      return views;
    }
  }

  private static class FinderByType<T extends View> implements LayoutTraverser.Processor {
    private final Class<T> type;
    private final List<T> views;

    private FinderByType(Class<T> type) {
      this.type = type;
      views = new ArrayList<T>();
    }

    @Override
    @SuppressWarnings("unchecked")
    public void process(View view) {
      if (type.isInstance(view)) {
        views.add((T) view);
      }
    }

    public List<T> getViews() {
      return views;
    }
  }
}

Help fellow developers by tweeting or sharing this post!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值