2012年2月22日水曜日

List<T> findViewsWithClass(View v, Class<T>)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

android.view.ViewといえばfindViewById(int)ですよねー。
実はそれ以外にもfindViewWithTag (Object tag)やfindViewsWithText(ArrayList, CharSequence, int)てのがあるようです。
使い所がよくわかりませんがなんか使えそうですね。

個人的にはViewのクラス名で取り出したいなーと、例えばjavascriptのgetElementsByTagName(name)のノリだと言うと判ると思います。

List<T> findViewsWithClass(View v, Class<T>)


はい、完成。本当は v instanceof Tってやりたかったけど怒られました。仕方なくClassのフルネームで比較してます。なのでサブクラスとかまでは検出できません。

public static <T extends View> List<T> findViewsWithClass(View v, Class<T> clazz){
  List<T> views = new ArrayList<T>();
  findViewsWithClass(v, clazz, views);
  return views;
 }
 
 private static <T extends View> void findViewsWithClass(View v, Class<T> clazz, List<T> views){
  if(v.getClass().getName().equals(clazz.getName())){
   views.add((T)v);
  }
  if(v instanceof ViewGroup){
   ViewGroup g = (ViewGroup)v;
   for(int i = 0; i < g.getChildCount(); i++){
    findViewsWithClass(g.getChildAt(i), clazz, views);
   }
  }
 }

※追記20120223
@zaki50さんからツッコミが。ありがとうございます!!



直した!。これの場合だとサブクラスまでがっつり取れる。

 private static <T extends View> void findViewsWithClass(View v, Class<T> clazz, List<T> views) {
  if (clazz.isAssignableFrom(v.getClass())){
   views.add(clazz.cast(v));
  }
  if (v instanceof ViewGroup) {
   ViewGroup g = (ViewGroup) v;
   for (int i = 0; i < g.getChildCount(); i++) {
    findViewsWithClass(g.getChildAt(i), clazz, views);
   }
  }
 }

使う


こう使うとよさげ。例えばこういうレイアウト

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="mogeee" >
    </TextView>
    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" >
    </ImageView>
    <LinearLayout
        android:id="@+id/main_list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    </LinearLayout>
</LinearLayout>

こういうコードで要素を取り出せます。以下はTextViewを取り出してます。

List<TextView> views = findViewsWithClass(v, TextView.class);
        if(views.isEmpty()){
         Log.d(TAG, "not found");
        }
        else{
         Log.d(TAG, "find:"+views.size());
        }

0 件のコメント:

コメントを投稿