include,viewStub标签的使用以及setWillNotDraw()的作用
转自:http://www.cnblogs.com/transmuse/archive/2011/05/12/2041544.html
===========================================================================
include,viewStub标签的使用
先说include标签,include标签的主要作用是复用已经写好的布局文件,但是有局限,因为include标签只能覆盖被引用布局的width,high,margin,weight等基本属性,无法修改引用布局中的子view的属性,它属于一成不变的引用,也不是说不能修改,只能在程序中动态的修改,所以include标签可以用,但不要去强用这个标签,会造成不必要的麻烦
再说viewStub标签
他的好处是如果不调用这个对象的inflate方法,那么这个对象就不会被实例化,当你需要这个布局的时候,调用他的inflate方法,就会绘制这个布局,这样能够节省内存。
疑议:没有inflate前的view和设置他的visible的属性为gone,有没有区别呢?
viewStub的默认属性是invisible,不是gone,通过设置他为visible或者调用他的inflate方法,都可以实现加载这个view,他继承自view,可以在运行时加载,此外他还不同于view设置invisible,view设置为invisible后,该view会被inflate,会占据一定的空间,但是viewStub不会。
再来看看view的gone属性,This view is invisible, and it doesn't take any space for layout purposes,那么设置了gone的view会被调用inflate方法吗?不会,因为他不占据空间,到现在为止,好像viewStub和gone的功能是类似的,看下面一段从ViewStub类中摘出来的一段代码
1 private void initialize(Context context) { 2 mContext = context; 3 setVisibility(GONE); 4 setWillNotDraw(true); 5 }
首先设置这个view的visible属性为gone,然后有设置了该类不能进行draw绘制。
ViewStub的原理是:ViewStub的属性设置为gone,并且不会被绘制,当设置了 setWillNotDraw(true)后,他的onDraw方法不会被调用,并且在他的onMeasure方法中,设置他的长度和宽度都为0,这样这个类就不会占用空间了,因为ViewStub是包含其他的布局文件,类似于include,ViewStub也是个view,自己本身能够被创建,但是他包含的布局文件是不会被加载的,即不会被inflate,所以也就不会消耗太多内存。如何保证ViewStub包含的布局文件不会被加载:
主要是通过设置 setWillNotDraw(true)方法。
这里引申一个网友的一篇文章:
一.引言: 想必大家以前也遇到過這個問題:出於項目的需要,我們有時需要新建一個直接或者間接繼承View的類,以便複寫View提供的onDraw()方法,但有時我們反而得不到我們想要的結果,今天就說一下onDraw()方法不被執行的解決方法。你可能也在onDraw()方法裡面設置了斷點或log,卻發現程序並沒有執行onDraw()方法,那麼你需要在你直接或者間接繼承View的類的構造函數中加入下面的語句: setWillNotDraw(false); 二.解釋: 那麼加這條語句的作用是什麼?先看API: If this view doesn't do any drawing on its own, set this flag to allow further optimizations. By default, this flag is not set on View, but could be set on some View subclasses such as ViewGroup. Typically, if you override onDraw(Canvas) you should clear this flag. 本人外語基礎不是很好,簡要翻譯一下,如果翻譯的不好,不要扔磚啊,重複一句我的語言:要想像,沒有了想像,世界會是什麼樣。嘿嘿: 如果在當前的view上面不做任何的繪製操作,需要設置這個標記以便將來的更好的需要,默認的,這個標記在View裡是不設定的。但是像View的一些子類如ViewGroup是可以設定的,典型的,你如果複寫了onDraw(Canvas)方法,你需要清除此標記。 那麼正好,我們所實現的就是View的子類:LinearLayout,當然你也可以繼承其他的子類如: AbsoluteLayout,AdapterView<T extends Adapter>,FrameLayout,LinearLayout,RelativeLayout,SlidingDrawer,子類就不說了,你可以自己去查文檔。 這條語句要放在繼承類的構造函數中,如: public class BackgroundLayout extends LinearLayout { public BackgroundLayout(Context context, int position) { super(context); // TODO Auto-generated constructor stub setWillNotDraw(false); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); } } } 三,擴展看法: eoeandroid上面Little關於這條語句的看法是: 设置view是否更改,如果开发者用自定义的view,重写ondraw()应该将调用此方法设置为false,这样程序会调用自定义的布局。 在此引用一下。 其實從這條語句的字面意思上可以看出:setWillNotDraw(false);就是設置將不繪畫嗎?你重寫了onDraw()當然是要進行繪畫了,所以應將此語句參數置為false.