溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

addView遇到的坑及其解決

發(fā)布時間:2020-06-26 00:52:04 來源:網(wǎng)絡(luò) 閱讀:3523 作者:一劍圍城 欄目:開發(fā)技術(shù)

   代碼中給容器動態(tài)添加子View時遇到一些問題,當(dāng)時還是糾結(jié)許久的。擅總結(jié)者無敵,寫下此篇總結(jié),問題比較的簡單,希望對新手有所幫助。

 

使用場景:

情況一:

View view = View.inflate(this, R.layout.item_contact,null);

view.getLayoutParams() == null

情況二:

View view =getLayoutInflater().inflate(R.layout.item_contact, null, false);

view.getLayoutParams() == null

情況三:

View view =getLayoutInflater().inflate(R.layout.item_contact, mContainer, false);

或者:View view =LayoutInflater.from(this).inflate(R.layout.item_contact, mContainer, false);

view.getLayoutParams() != null

 

//添加到指定父容器

mContainer.addView(view);

 

View.inflate(this, R.layout.item_contact, mContainer);

作用:創(chuàng)建一個指定布局的View對象,并加入到mContainer的父容器中。

 

getLayoutInflater().inflate(R.layout.item_contact,mContainer, true);

作用:創(chuàng)建一個指定布局的View對象,并加入到mContainer的父容器中。

 

View.inflate(this,resource, null);

這種方式創(chuàng)建的View對象沒有LayoutParams。沒指定父容器(null),也就是寬高參數(shù)是空的。

此時addView方法中會調(diào)用generateDefaultLayoutParams()生成默認(rèn)的寬高參數(shù):

就是:new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

如果你的原本布局寬高不是wrap_content,wrap_content,那么就有問題了。

 

LayoutInflater.inflate方法

LayoutInflater.inflate(int resource, ViewGroup root,boolean attachToRoot)

resource:資源文件id

root:父容器對象

attachToRoot:是否添加到父容器中

備注:

attachToRoot == true;root會作為創(chuàng)建的View對象的父容器

attachToRoot == false;root會為創(chuàng)建的View對象提供LayoutParams參數(shù)

 

對于新手而言,問題可能在于:

View view = View.inflate(this, R.layout.item_contact,null);

mContainer.addView(view);添加到mContainer父容器中

 

問題在于:此時的view是沒有LayoutParams的,需要:

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(

LinearLayout.LayoutParams.WRAP_CONTENT,

LinearLayout.LayoutParams.MATCH_PARENT);

需要使用:mContainer.addView(view, params);這樣才能正確體現(xiàn)View布局的寬高參數(shù)。

上述代碼相當(dāng)于如下:

View.inflate(this, R.layout.item_contact, mContainer);//一行代碼搞定

而同一個View對象,不能同時有兩個父容器,此時就無需再調(diào)用addView(view);添加了。

如果不需要對View對象進(jìn)行操作,還免去創(chuàng)建引用變量的資源消耗。(這里有坑)

 

另外一個類似方法:

getLayoutInflater().inflate(int resource, ViewGrouproot, boolean attachToRoot)

事實上,從源碼可見:

View.inflate(this, resource, null);//實現(xiàn)原理可歸納為:

LayoutInflater.from(this).inflate(resource, root, root!= null);

 

總結(jié):為容器添加子View的方式:

方式一://方便重新指定LayoutParams

View view = View.inflate(this, R.layout.item_contact,null);

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(...);//重新指定LayoutParams。

mContainer.addView(view, params);

方式二(同一):

View view =LayoutInflater.from(this).inflate(R.layout.item_contact, mContainer, false);

mContainer.addView(view);

 

方式三://適合于使用布局中指定的LayoutParams

View.inflate(this, R.layout.item_contact, mContainer);

方式四(同四):

LayoutInflater.from(this).inflate(R.layout.item_contact,mContainer, true);

 

備注:顯然,方式三、四使用更簡潔,方式一、二則適用于布局重用于不適合布局中指定的LayoutParams的情況。

==================================================================================================

坑坑坑坑

LayoutInflater的API文檔:

View inflate (int resource, ViewGroup root)

The root View of the inflated hierarchy. If root was supplied, this is the root View; otherwise it is the root of the inflated XML file.


View inflate (int resource, ViewGroup root, boolean attachToRoot)

The root View of the inflated hierarchy. If root was supplied and attachToRoot is true, this is root; otherwise it is the root of the inflated XML file.


例如:

View view = View.inflate(this, resoutceId, mContainer);

如果傳入root不為空,

那么此時view表示mContainer和新創(chuàng)建出來的對象結(jié)合后的root View,這里就是父容器mContainer。

當(dāng)你需要對每個新創(chuàng)建的View對象進(jìn)行操作時,如統(tǒng)一點擊事件等,則不能傳入父容器。


View view = View.inflate(this,resoutceId, null);

mContainer.addView(view);

如果傳入root為空

那么此時view表示新創(chuàng)建出來的View對象,就是resoutceId指定的布局的根元素。

例如:resoutceId根元素是TextView,則view是TextView對象


另外:

LayoutInflater.from(this).inflate(resoutceId, mContainer));

//默認(rèn)attach到mContainer,返回mContainer


LayoutInflater.from(this).inflate(resoutceId, mContainer, true));

//attach到mContainer,返回mContainer


LayoutInflater.from(this).inflate(resoutceId, mContainer, false)); 

//沒有attach到mContainer,返回resoutceId的根元素


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI