日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

正确使用ViewStub

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 正确使用ViewStub 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在使用ViewStub,在使用的過程中遇到了一些問題,所以現在就在這里記錄一下,也免得后面使用的人少走一些坑。事情是這樣的,由于項目中要用ViewStub對原有的一些布局頁面進行懶加載,提升用戶體驗,所以簡單了解了一下ViewStub的用法后,就將原來的需要懶加載的Layout單獨設置為一個xml文件。本來以為是沒有問題,但是一看原來并不是這么簡單。有好幾個需要注意的點,現在分開來講:

一、ViewStub多次inflate引發的exception:

ViewStub must have a non-null ViewGroup viewParent 相信第一次用的人應該都會遇到過這個的問題,我們進去inflate()的方法源碼看看,

public View inflate() {

final ViewParent viewParent = getParent(); if (viewParent != null && viewParent instanceof ViewGroup) { if (mLayoutResource != 0) {
final ViewGroup parent = (ViewGroup) viewParent;
final LayoutInflater factory;
if (mInflater != null) {
factory = mInflater;
} else {
factory = LayoutInflater.from(mContext);
}
final View view = factory.inflate(mLayoutResource, parent,
false); if (mInflatedId != NO_ID) { view.setId(mInflatedId);
} final int index = parent.indexOfChild(this); parent.removeViewInLayout(this); final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (layoutParams != null) {
parent.addView(view, index, layoutParams);
} else {
parent.addView(view, index);
} mInflatedViewRef = new WeakReference<View>(view);
if (mInflateListener != null) {
mInflateListener.onInflate(this, view);
} return view; } else {
throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
}
}

是不是很熟悉?由于ViewStub第一次inflate的時候,就已經將需要顯示的布局替換掉自己了,所以第二次inflate的時候,getParent()是null,所以就會報異常。解決方法是inflate()的時候將view保存起來,然后下次判斷這個View是否為NUll,如果是null就inflate().否則就直接使用這個view,還有一種就是setOnInflateListener,這個網上也有文章,這里不細說。如果被包含的layout的子View沒有用戶邏輯操作的,可以使用ViewStub的setVisibility()來控制顯示和隱藏。里面已經做了inflate多次的判斷的了,不會有異常的。

二、被包含的layout里面設置layout_margin屬性失效而設置padding屬性有效的問題。這個問題需要看源碼才能解答,所以就看了一下源碼。還是看inflate()方法。

final?ViewGroup.LayoutParams layoutParams = getLayoutParams();
if?(layoutParams !=?null) {
parent.addView(view, index, layoutParams);
}?else?{
parent.addView(view, index);
}

看到這一段代碼了嗎?有個getLayoutParams() 以及 parent.addView方法??梢钥吹?#xff0c;getlayoutParams獲取的是VeiwStub的LayoutParams,而不是被顯示的Layout_params。所以,addView的時候,要么就是將ViewStub的layoutParams賦值給將要顯示的view,要么直接調用addView(view,index),所以如果想要margin有效果,我們之能將layout_margin放到ViewStub里面,同理,如果是在相對布局里面,below_? above_這些屬性控制都要放到viewStub那里,而不是放到將要顯示的layout里面。那為什么padding會在將要顯示的layout中起作用呢?這就要好好理解一下ViewGroup.LayoutParams layoutParams了,你會發現padding并不屬于ViewGroup.LayoutParams layoutParams里面的,而是屬于View的成員變量,這也就解釋了為什么padding屬性不會失效了,之前還以為padding設置ViewGroup.LayoutParams里面設置的呢。好了,這里相信大家對ViewStub都有一個很清晰的了解了,有什么問題,可以相互交流哦,如何比較優雅的使用ViewStub呢?經過本人試驗,個人還是比較推薦使用setOnInflateListener,因為它只會被調用一次,就是剛inflate的時候,而且無論無論inflate的layout中是不是有其它的事件監聽,它都可以實現。

我建了個qq群:207678498

總結

以上是生活随笔為你收集整理的正确使用ViewStub的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。