Android解决使用findViewById时需要对返回值进行类型转换问题的辅助类

来源:互联网 发布:sql 使用别名 编辑:程序博客网 时间:2024/05/22 12:00

各位看这个时候请注意,我试用了一下,发现这样找到的控件,给控件设置了onClick事件的监听器,发现点击的时候触发不到onClick事件。   

在我们的开发工作时,findViewById可能是用得最多的函数之一,但它特别讨厌的地方就是我们经常需要对返回的view进行类型转换,输入麻烦、代码丑陋,例如以前我们在Activity中找一些子控件一般是这样 :

@Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //  查找子控件        TextView textView = (TextView)findViewById(R.id.my_textview);         ImageView imageView = (ImageView)findViewById(R.id.my_imageview);         ListView listView = (ListView)findViewById(R.id.my_listview);}

如果页面中的控件比较多,就会有很多的类型转换,这么搞下去还能不能在Android上愉快地开发项目了? 而使用ViewFinder则免去了类型转换,ViewFinder是一个在一个布局中找某个子控件的工具类,用户需要在使用时调用ViewFinder.initContentView函数来初始化ContentView,参数为Context和布局id。然后使用ViewFinder.findViewById来获取需要的view,返回的view则直接是你接收的类型,而不需要进行强制类型转换。

示例如下 :

@Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 初始化        ViewFinder.initContentView(this, R.layout.activity_main) ;        // 查找子控件        TextView textView = ViewFinder.findViewById(R.id.my_textview);         ImageView imageView = ViewFinder.findViewById(R.id.my_imageview);         ListView listView = ViewFinder.findViewById(R.id.my_listview);}
ViewFinder的实现

[java] view plaincopy
  1. /** 
  2.  * view finder, 方便查找View。用户需要在使用时调用initContentView, 
  3.  * 将Context和布局id传进来,然后使用findViewById来获取需要的view 
  4.  * ,findViewById为泛型方法,返回的view则直接是你接收的类型,而不需要进行强制类型转换.比如, 
  5.  * 以前我们在Activity中找一个TextView一般是这样 :  
  6.  * TextView textView = (TextView)findViewById(viewId);  
  7.  * 如果页面中的控件比较多,就会有很多的类型转换,而使用ViewFinder则免去了类型转换, 
  8.  * 示例如下 :  
  9.  * TextView textView = ViewFinder.findViewById(viewId); 
  10.  *  
  11.  * @author mrsimple 
  12.  */  
  13. public final class ViewFinder {  
  14.   
  15.     /** 
  16.      * LayoutInflater 
  17.      */  
  18.     static LayoutInflater mInflater;  
  19.   
  20.     /** 
  21.      * 每项的View的sub view Map 
  22.      */  
  23.     private static SparseArray<View> mViewMap = new SparseArray<View>();  
  24.   
  25.     /** 
  26.      * Content View 
  27.      */  
  28.     static View mContentView;  
  29.   
  30.     /** 
  31.      * 初始化ViewFinder, 实际上是获取到该页面的ContentView. 
  32.      *  
  33.      * @param context 
  34.      * @param layoutId 
  35.      */  
  36.     public static void initContentView(Context context, int layoutId) {  
  37.         mInflater = LayoutInflater.from(context);  
  38.         mContentView = mInflater.inflate(layoutId, nullfalse);  
  39.         if (mInflater == null || mContentView == null) {  
  40.             throw new RuntimeException(  
  41.                     "ViewFinder init failed, mInflater == null || mContentView == null.");  
  42.         }  
  43.     }  
  44.   
  45.     /** 
  46.      * @return 
  47.      */  
  48.     public static View getContentView() {  
  49.         return mContentView;  
  50.     }  
  51.   
  52.     /** 
  53.      * @param viewId 
  54.      * @return 
  55.      */  
  56.     @SuppressWarnings("unchecked")  
  57.     public static <T extends View> T findViewById(int viewId) {  
  58.         // 先从view map中查找,如果有的缓存的话直接使用,否则再从mContentView中找  
  59.         View tagetView = mViewMap.get(viewId);  
  60.         if (tagetView == null) {  
  61.             tagetView = mContentView.findViewById(viewId);  
  62.             mViewMap.put(viewId, tagetView);  
  63.         }  
  64.         return tagetView == null ? null : (T) mContentView.findViewById(viewId);  
  65.     }  
  66. }  
0 0