<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      安卓筆記俠

      專(zhuān)注安卓開(kāi)發(fā)

      導(dǎo)航

      布局優(yōu)化之ViewStub源碼分析

      源碼分析

        1 @RemoteView  
        2 public final class ViewStub extends View {  
        3     private int mInflatedId;  
        4     private int mLayoutResource;  
        5   
        6     private WeakReference<View> mInflatedViewRef;  
        7   
        8     private LayoutInflater mInflater;  
        9     private OnInflateListener mInflateListener;  
       10   
       11     public ViewStub(Context context) {  
       12         this(context, 0);  
       13     }  
       14   
       15     /**  
       16      * Creates a new ViewStub with the specified layout resource.  
       17      *  
       18      * @param context The application's environment.  
       19      * @param layoutResource The reference to a layout resource that will be inflated.  
       20      */  
       21     public ViewStub(Context context, @LayoutRes int layoutResource) {  
       22         this(context, null);  
       23   
       24         mLayoutResource = layoutResource;  
       25     }  
       26   
       27     public ViewStub(Context context, AttributeSet attrs) {  
       28         this(context, attrs, 0);  
       29     }  
       30   
       31     public ViewStub(Context context, AttributeSet attrs, int defStyleAttr) {  
       32         this(context, attrs, defStyleAttr, 0);  
       33     }  
       34   
       35     public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {  
       36         super(context);  
       37   
       38         final TypedArray a = context.obtainStyledAttributes(attrs,  
       39                 R.styleable.ViewStub, defStyleAttr, defStyleRes);  
       40         mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);  
       41         mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);  
       42         mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);  
       43         a.recycle();  
       44   
       45         setVisibility(GONE); // 默認(rèn)不可見(jiàn)  
       46         setWillNotDraw(true); // 如果View不繪制任何內(nèi)容,設(shè)置這個(gè)標(biāo)記可以?xún)?yōu)化性能,默認(rèn)View沒(méi)有設(shè)置這個(gè)標(biāo)記,如果重寫(xiě)onDraw,就不要設(shè)置這個(gè)標(biāo)記  
       47     }  
       48   
       49     @Override  
       50     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
       51         setMeasuredDimension(0, 0); // 測(cè)量時(shí)尺寸為0  
       52     }  
       53   
       54     @Override  
       55     public void draw(Canvas canvas) { // 不繪制內(nèi)容  
       56     }  
       57   
       58     @Override  
       59     protected void dispatchDraw(Canvas canvas) {  
       60     }  
       61 ..... 省去部分代碼  
       62   
       63     private View inflateViewNoAdd(ViewGroup parent) {  
       64         final LayoutInflater factory;  
       65         if (mInflater != null) {  
       66             factory = mInflater;  
       67         } else {  
       68             factory = LayoutInflater.from(mContext);  
       69         } // 通過(guò)inflate填充布局  
       70         final View view = factory.inflate(mLayoutResource, parent, false);  
       71   
       72         if (mInflatedId != NO_ID) {  
       73             view.setId(mInflatedId);  
       74         }  
       75         return view;  
       76     }  
       77   
       78     private void replaceSelfWithView(View view, ViewGroup parent) {  
       79         final int index = parent.indexOfChild(this);  
       80         parent.removeViewInLayout(this); // 移除ViewStub,后面不能在inflate  
       81   
       82         final ViewGroup.LayoutParams layoutParams = getLayoutParams(); // 獲得ViewStub的布局參數(shù)  
       83         if (layoutParams != null) {  
       84             parent.addView(view, index, layoutParams); // 把ViewStub指定的布局添加到parent中  
       85         } else {  
       86             parent.addView(view, index);  
       87         }  
       88     }  
       89   
       90     /**  
       91      * Inflates the layout resource identified by {@link #getLayoutResource()}  
       92      * and replaces this StubbedView in its parent by the inflated layout resource.  
       93      *  
       94      * @return The inflated layout resource.  
       95      *  
       96      */  
       97     public View inflate() {  
       98         final ViewParent viewParent = getParent(); // 獲取ViewStub的parent  
       99   
      100         if (viewParent != null && viewParent instanceof ViewGroup) {  
      101             if (mLayoutResource != 0) {  
      102                 final ViewGroup parent = (ViewGroup) viewParent;  
      103                 final View view = inflateViewNoAdd(parent);  
      104                 replaceSelfWithView(view, parent);  
      105   
      106                 mInflatedViewRef = new WeakReference<>(view);  
      107                 if (mInflateListener != null) {  
      108                     mInflateListener.onInflate(this, view);  
      109                 }  
      110   
      111                 return view;  
      112             } else {  
      113                 throw new IllegalArgumentException("ViewStub must have a valid layoutResource");  
      114             }  
      115         } else {  
      116             throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");  
      117         }  
      118     }  
      119   
      120     /**  
      121      * Specifies the inflate listener to be notified after this ViewStub successfully  
      122      * inflated its layout resource.  
      123      *  
      124      * @param inflateListener The OnInflateListener to notify of successful inflation.  
      125      *  
      126      * @see android.view.ViewStub.OnInflateListener  
      127      */  
      128     public void setOnInflateListener(OnInflateListener inflateListener) {  
      129         mInflateListener = inflateListener;  
      130     }  
      131   
      132     /**  
      133      * Listener used to receive a notification after a ViewStub has successfully  
      134      * inflated its layout resource.  
      135      *  
      136      * @see android.view.ViewStub#setOnInflateListener(android.view.ViewStub.OnInflateListener)   
      137      */  
      138     public static interface OnInflateListener {  
      139         /**  
      140          * Invoked after a ViewStub successfully inflated its layout resource.  
      141          * This method is invoked after the inflated view was added to the  
      142          * hierarchy but before the layout pass.  
      143          *  
      144          * @param stub The ViewStub that initiated the inflation.  
      145          * @param inflated The inflated View.  
      146          */  
      147         void onInflate(ViewStub stub, View inflated);  
      148     }  
      149   
      150     /** @hide **/  
      151     public class ViewReplaceRunnable implements Runnable {  
      152         public final View view;  
      153   
      154         ViewReplaceRunnable(View view) {  
      155             this.view = view;  
      156         }  
      157   
      158         @Override  
      159         public void run() {  
      160             replaceSelfWithView(view, (ViewGroup) getParent());  
      161         }  
      162     }  
      163 }  

      這是什么玩應(yīng)兒呢?其實(shí)就是一個(gè)輕量級(jí)的頁(yè)面,我們通常使用它來(lái)做預(yù)加載處理,來(lái)改善頁(yè)面加載速度和提高流暢性,ViewStub本身不會(huì)占用層級(jí),它最終會(huì)被它指定的層級(jí)取代。 
      在一些場(chǎng)合取代android:visibility=”gone”的用法,因?yàn)楸籫one掉的布局不斷是會(huì)同時(shí)創(chuàng)建對(duì)象的。那為什么使用ViewStub就高效呢, 
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      setMeasuredDimension(0, 0); 
      }

      @Override 
      public void draw(Canvas canvas) { 

      由onMeasure()方法和draw()方法可以看出, ViewStub的初始寬高都是零,所以他開(kāi)始不會(huì)占用空間,其次draw()方法也沒(méi)有執(zhí)行任何的繪制,由這兩個(gè)方法就可以看出,ViewStub的確很高效。 
      在代碼中要操縱ViewStub的時(shí)候,要首先使用viewstub.inflate()方法,將其所擁有的View初始化進(jìn)去。否則會(huì)報(bào)空指針錯(cuò)誤。 
      但ViewStub也不是萬(wàn)能的,下面總結(jié)下ViewStub能做的事兒和什么時(shí)候該用ViewStub,什么時(shí)候該用可見(jiàn)性的控制。

      首先來(lái)說(shuō)說(shuō)ViewStub的一些特點(diǎn):
      
      1. ViewStub只能Inflate一次,之后ViewStub對(duì)象會(huì)被置為空。按句話(huà)說(shuō),某個(gè)被ViewStub指定的布局被Inflate后,就不會(huì)夠再通過(guò)ViewStub來(lái)控制它了。
      2. ViewStub只能用來(lái)Inflate一個(gè)布局文件,而不是某個(gè)具體的View,當(dāng)然也可以把View寫(xiě)在某個(gè)布局文件中。
      
      基于以上的特點(diǎn),那么可以考慮使用ViewStub的情況有:
      1. 在程序的運(yùn)行期間,某個(gè)布局在Inflate后,就不會(huì)有變化,除非重新啟動(dòng)。
      因?yàn)閂iewStub只能Inflate一次,之后會(huì)被置空,所以無(wú)法指望后面接著使用ViewStub來(lái)控制布局。所以當(dāng)需要在運(yùn)行時(shí)不止一次的顯示和隱藏某個(gè)布局,那么ViewStub是做不到的。這時(shí)就只能使用View的可見(jiàn)性來(lái)控制了。
      2. 想要控制顯示與隱藏的是一個(gè)布局文件,而非某個(gè)View。
      因?yàn)樵O(shè)置給ViewStub的只能是某個(gè)布局文件的Id,所以無(wú)法讓它來(lái)控制某個(gè)View。
      所以,如果想要控制某個(gè)View(如Button或TextView)的顯示與隱藏,或者想要在運(yùn)行時(shí)不斷的顯示與隱藏某個(gè)布局或View,只能使用View的可見(jiàn)性來(lái)控制。

       

      posted on 2018-05-23 14:27  安卓筆記俠  閱讀(437)  評(píng)論(0)    收藏  舉報(bào)

      主站蜘蛛池模板: 高清美女视频一区二区三区| 霸州市| 风流少妇又紧又爽又丰满| 一区二区三区四区亚洲综合| 中文字幕不卡在线播放| 久久99国产精品尤物| 美女胸18下看禁止免费视频| 久久五月丁香激情综合| 国产成人精品午夜福利| 精品偷拍一区二区三区| 欧美一本大道香蕉综合视频| 青草青草久热国产精品| 男女啪啪高潮激烈免费版| 成人久久精品国产亚洲av| 国产精品免费AⅤ片在线观看| 深夜在线观看免费av| 欧美激欧美啪啪片| 免费看久久妇女高潮a| 国产999久久高清免费观看| 色综合天天综合网国产人| 国产一区二区在线有码| 成人性生交大片免费看r老牛网站| 久久亚洲美女精品国产精品| 国产AV影片麻豆精品传媒| 自拍视频在线观看成人| 亚洲首页一区任你躁xxxxx| 久久九九99这里有视频| 婷婷丁香五月深爱憿情网| 欧美牲交a欧美牲交aⅴ免费真| 九九色这里只有精品国产| 50路熟女| 桃花岛亚洲成在人线AV| 国产无遮挡又黄又大又爽| 亚洲丰满熟女一区二区v| 一区二区三区四区亚洲自拍| 国产午夜福利片在线观看| 少妇特黄a一区二区三区| 国产极品美女高潮无套| 亚洲国产永久精品成人麻豆| 久久99精品国产99久久6尤物| 国产麻豆精品手机在线观看|