多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開(kāi)源 > 綜合技術(shù) > Android初始化的時(shí)候獲取加載的布局的寬高(續(xù))--RelativeLayout的陷阱

Android初始化的時(shí)候獲取加載的布局的寬高(續(xù))--RelativeLayout的陷阱

來(lái)源:程序員人生   發(fā)布時(shí)間:2014-12-17 08:38:44 閱讀次數(shù):4983次

接著上次的問(wèn)題,已介紹過(guò),在初始化或說(shuō)OnCreate方法中獲得加載的布局的寬高,最后說(shuō)到,調(diào)用view.measure(0, 0);然后在調(diào)用getMeasuredWidth和getMeasuredHeight就能夠取得丈量的寬高。可以參考:Android如何在初始化的時(shí)候獲得加載的布局的寬高
今天在寫(xiě)類(lèi)似的效果時(shí),給ListView加載1個(gè)頭部視圖,通過(guò)listView$addHeadView添加到ListView的頭部。為了描寫(xiě)起來(lái)簡(jiǎn)單起見(jiàn),這個(gè)頭部視圖的布局我做了簡(jiǎn)化為下面:headview.xml

<?xml version="1.0" encoding="utf⑻"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/information_top" /> </RelativeLayout>

然后在初始化的時(shí)候想獲得該布局的寬高,就這樣做了:

//布局加載器 private LayoutInflater inflater; //頭部的View private View headView; //頭部View的寬 private int headViewWidth; //頭部View的高 private int headViewHeight; inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); headView = inflater.inflate(R.layout.headview, null); headView.measure(0, 0); headViewWidth = headView.getMeasuredWidth(); headViewHeight = headView.getMeasuredHeight(); Log.i(TAG, "headViewWidth-->" + headViewWidth + " headViewHeight-->" + headViewHeight); addHeaderView(headView);

結(jié)果。。。。。

程序崩潰了!尼瑪,不是說(shuō)好的headView.measure(0, 0);調(diào)用完就可以獲得到布局的寬高了嘛,怎樣這句好報(bào)錯(cuò)空指針異常了?

然后把布局修改成線性布局

<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/information_top" /> </LinearLayout>

居然就行了。。。


也獲得到了丈量的寬高:


接下來(lái)又開(kāi)始了對(duì)問(wèn)題的研究。為了簡(jiǎn)化問(wèn)題,還是依照上次的此路。在上次的基礎(chǔ)上添加布局viewgroup_relativelayout.xml,其實(shí)就是將外層的LinearLayout修改成RelativeLayout了,其他地方未變。加載該布局,然后丈量寬高。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <View android:layout_width="50dp" android:layout_height="50dp" /> </RelativeLayout>

看結(jié)果:


View,textview和線性布局的ViewGroup和上次的結(jié)果1樣。但是將相對(duì)布局的ViewGroup直接掛掉。。剛開(kāi)始還是特別的不爽的,為何常常遇到問(wèn)題,不過(guò)1想,解決問(wèn)題的進(jìn)程就是水平提高的進(jìn)程,所以打起精神進(jìn)行研究。嘿嘿~

通過(guò)比較發(fā)現(xiàn)RelativeLayout出錯(cuò)了,所以很容易將空指針異常的地方定位在RelativeLayout的onMeasure函數(shù)中。

但是這個(gè)函數(shù)比較復(fù)雜了。兩百多行代碼,里面牽扯了很多的域變量和函數(shù),讀起來(lái)挺累的。因此在網(wǎng)上搜了好久,在eoe上面看到有人說(shuō)了下面的方法:

如果使用Inflater的情況下會(huì)出現(xiàn)以上毛病,緣由是用Inflater渲染組件的時(shí)候并沒(méi)有給其指定父控件,所以渲染器不會(huì)去解析width 和 height屬性,就會(huì)致使空指針異常。

解決方法:

view.setLayoutParams(newLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));指定寬度和高度,然后調(diào)用measure方法就OK。

其實(shí)這個(gè)說(shuō)法前面就研究過(guò),確切是這模樣的,但是LinearLayout為何沒(méi)出問(wèn)題RelativeLayout就出問(wèn)題了呢,所以還是沒(méi)有說(shuō)明白緣由在哪里。

我嘗試了1下確切弄定了,緣由尚不清楚,那就肯定需要查源代碼了。在這個(gè)指點(diǎn)下給我提供了方向就是極可能在onMeasure方法里面調(diào)用了該相對(duì)布局的參數(shù)mLayoutParams,由于本來(lái)為null,那末調(diào)用的話就會(huì)報(bào)告空指針異常!

接下來(lái)就在源碼的onMeasure函數(shù)里面將所有出現(xiàn)mLayoutParams的地方打上斷點(diǎn)。然后斷點(diǎn)調(diào)試

RelativeLayou類(lèi)(我查看的是4.2的源碼)

//493行 if (mLayoutParams.width >= 0) { width = Math.max(width, mLayoutParams.width); } //523行 if (mLayoutParams.height >= 0) { height = Math.max(height, mLayoutParams.height); }

果然mLayoutParams變量不存在為null。

到現(xiàn)在為止問(wèn)題就清楚了。由于調(diào)用headView.measure(0, 0);的時(shí)候是通過(guò)inflate(R.layout.headview, null);方式加載的布局,因此設(shè)置的外層RelativeLayout布局的LayoutParams是null的,恰巧相對(duì)布局沒(méi)有檢查是不是為null就直接調(diào)用了mLayoutParams.width或mLayoutParams.height,因此就報(bào)空指針毛病了。這多是1個(gè)bug吧我認(rèn)為。

既然知道了問(wèn)題是出在了這里了,那末也很容易解決了。

最少有以下的解決方法:

1,加載布局的時(shí)候通過(guò)inflater.inflate(R.layout.viewgroup_relativelayout,(ViewGroup) findViewById(R.id.mainLayout),false);方式加載。這樣的話會(huì)設(shè)置他的布局參數(shù)。

2 手動(dòng)設(shè)置布局參數(shù)添加上

lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); setLayoutParams(lp);


現(xiàn)在再來(lái)看上1篇博客里面講的這個(gè)方法:

private void measureView(View child) { ViewGroup.LayoutParams lp = child.getLayoutParams(); if(lp == null){ lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); // child.setLayoutParams(lp); } //headerView的寬度信息 int childMeasureWidth = ViewGroup.getChildMeasureSpec(0, 0, lp.width); int childMeasureHeight; if(lp.height > 0){ childMeasureHeight = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); } else { childMeasureHeight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);//未指定 } //將寬和高設(shè)置給child child.measure(childMeasureWidth, childMeasureHeight); }

看起來(lái)貌似就是為了不外層布局是RelativeLayout的情況對(duì)LayoutParams做了判斷!但是直接調(diào)用上面這個(gè)方法依然不行,由于new出來(lái)的LayoutParams沒(méi)有設(shè)置進(jìn)去,所以還需要調(diào)用child.setLayoutParams(lp);然后就弄定了。經(jīng)過(guò)測(cè)試ok!



回到博客開(kāi)始在ListView添加頭View所遇到的問(wèn)題也就很容易解決了。

1,將相對(duì)布局換成線性布局。

2,依然使用相對(duì)布局,使用上面說(shuō)的兩種方法設(shè)置外層的相對(duì)布局的布局參數(shù)。比如使用下面的方法,在家在布局的時(shí)候帶上父布局,結(jié)果弄定!好開(kāi)心

inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); headView = inflater.inflate(R.layout.headview, this,false); headView.measure(0, 0); //換成方法measureView (headView)也能夠 headViewWidth = headView.getMeasuredWidth(); headViewHeight = headView.getMeasuredHeight(); Log.i(TAG, "headViewWidth-->" + headViewWidth + " headViewHeight-->" + headViewHeight); addHeaderView(headView);

將headView.measure(0, 0);換成measureView (headView);也能夠的。

但是加載布局的時(shí)候不帶上父布局,調(diào)用的是headView =inflater.inflate(R.layout.headview, null);即便用下面代碼:

inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); headView = inflater.inflate(R.layout.headview, null); //headView.measure(0, 0); measureView(headView); headViewWidth = headView.getMeasuredWidth(); headViewHeight = headView.getMeasuredHeight(); Log.i(TAG, "headViewWidth-->" + headViewWidth + " headViewHeight-->" + headViewHeight); addHeaderView(headView);

程序居然又崩潰了。看調(diào)試結(jié)果:


不過(guò)不用擔(dān)心,這時(shí)候的毛病不是空指針了,而是類(lèi)轉(zhuǎn)換異常,相信通錯(cuò)誤誤很容易修改了

lp= new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT,AbsListView.LayoutParams.WRAP_CONTENT);

然后在運(yùn)行就行了,大功告成。最后的忠告就是需要自己需要丈量布局寬高的時(shí)候慎用RelativeLayout,猶如解決ScrollViewListView沖突的時(shí)候1種解決方法,這里我們只討論其中1個(gè)沖突就是:致使ListView的高度顯示不完全,出現(xiàn)只顯示部份內(nèi)容的情況。解決方法就是就是丈量ListView的總高度,然后設(shè)置1下,關(guān)鍵代碼以下。試想,如果這時(shí)候候如果各個(gè)itemRelativeLayout的話,肯定會(huì)出錯(cuò)。

private void setListViewHeight(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); }

最后,這些東西可能有些人寫(xiě)程序的時(shí)候都從沒(méi)遇到過(guò),固然也不影響寫(xiě)出漂亮的APP。但是我認(rèn)為不論是甚么問(wèn)題,都能鍛煉解決問(wèn)題的能力,都是有助于學(xué)習(xí)。

文字表達(dá)能力太差,表述能力是硬傷啊!

生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 337p日本欧洲亚洲大胆艺术图666 | 久草成人 | 国产日韩精品欧美一区 | 欧美大陆日韩一区二区三区 | www射射一区 | 2022精品福利在线小视频 | 国产精品久久久久毛片真精品 | 中文字幕第10页 | 国产一区二区福利 | 欧美成人天天综合在线视色 | 日本动漫片b站免费观看 | 最近最新中文字幕1页 | 羞羞视频免费网站日本 | 久久久久久久久毛片精品 | 亚洲一区二区三区视频 | 日本乱人伦片中文字幕三区 | 国产日本欧美在线观看乱码 | 国产精品久久现线拍久青草 | 91手机看片国产福利精品 | 免费 黄 色 人成 视频 | 最近免费中文字幕高清大全 | 国产精品特黄毛片 | 一区二区三区不卡在线观看 | 亚洲精品第一综合99久久 | 中文字幕一区二区三区免费看 | 二级毛片在线观看 | 国产片欧美片亚洲片久久综合 | hd性欧美俱乐部中文 | 日本免费一区二区三区三州 | 午夜免费播放观看在线视频 | 免费高清a级毛片在线播放 免费高清不卡毛片在线看 免费高清国产 | 亚洲精品久久久久网站 | 亚洲天堂第一 | 国产精品久久亚洲一区二区 | 欧美一级毛片100部 欧美一级毛片不卡免费观看 | 国产欧美另类性视频 | 日本一区二区三区四区在线观看 | 欧美激情免费a视频 | 日本一级毛片免费播放 | 国产一区二区三区四区五区六区 | 校园春色激情网 |