在使用listview的時候。自訂adapter,發現在getView裡列印日誌的時候,重複調用很多次?有時候 4次, 有時候10次,當我們在listview中移動的時候。每移動一列都會調用很多次,這樣大大影響到效率!
重寫的listview adapter中,在getView()方法中,列印語句時,相同的position列印了多次,修改方法:將布局檔案中ListView的高度改為“fill_parent” <ListView android:id="@+id/dynamic_list" android:layout_height="fill_parent" android:layout_width="fill_parent" android:scrollbars="vertical" android:layout_weight="1" android:drawSelectorOnTop="false" android:fadingEdgeLength="0dip" android:divider="@null" android:dividerHeight="0dip" android:cacheColorHint="#00000000" android:background="@color/listview_bg_color" />
把高設成wrap_content的時候。在listview裡載入幾行。日誌在 getview裡列印一下。是不是重複調用了?把高設定成fill_parent就成了。這個時候發現日誌還是重複調用?那就要看一下Listview的上一級布局的高是不是也是fill_parent的,如果不是。請改動吧。
如果我們在布局裡不止一個Listview。一個複雜好看的布局可能有很多。listview在布局的某個地方, 你會發現你調用了很多次getview, 這個速度是相當慢。對於這樣的情況,在修改布局的 時候,要考慮以下兩點:1.首先考慮需求布局和效能哪個更重要一點。2.考慮listview周邊哪個布局控制項影響到了它!
當我們最佳化的時候。首先要看一下有沒有影響到Listview重繪的控制項,比如。如果它上面和下面都有控制項。而且高都是wrap_content,那麼你就要設定成fill_parent或者固定高。這樣 listview在高上就不會重繪,這是最主要的一點。那左右是不是也有控制項有,那我們就也要調整,那就同高一樣的設定。一定要讓listview是一個固定在那個地方不動的。
其實說了這麼多。最主要的還是在我們進行布局的時候。要巧妙的運用每個控制項的屬性,以及瞭解控制項每個的原理。這樣在我們進行UI設計的時候,才能很好的去結合!
關於Adapter的getView方法中建立view的原理
position的確是要顯示的View在你的adapter裡面的位置
你自己心裡有一種先入為主的東西,擾亂了你的思維。
當你在滾動螢幕的時候,並不是說你只滾了一行,就只會有一次調用getView,實際上可能出現多次調用getView的(系統完全有可能多產生幾行View,以便在摸動的時候,達到平滑不滯後的效果)。
在getView裡面,你只能建立View,不可有自己的與介面無關的邏輯,因為你不知道getView什麼時候被調用,以什麼參數被調用。
而你要建立View,position參數是必須要使用的,所以不要懷疑這個參數。
另外,position絕對不是螢幕上的位置,而是資料在adapter裡面的位置,因為你建立View的時候,與它在螢幕上的位置沒有關係,你只是建立,至於顯示到哪裡,你並沒有做控制。
這個 先要理解了他的工作原理 才好分析原因。
如果你的螢幕只能顯示6行,所以position 的值就是0~5。
比如滾屏造成有一行出了屏,有一行新的入了屏
這個時候 新得到的view的 position 就會又充0計算
比如有2行進入的螢幕 那麼position 就是0~1了
所以列印就是 先列印0~5 然後你拖地列印0~1
總之,position絕對是一個合法的值,但你不要想當然的認為,某次getView,一定會傳一個position等於多少值的給你,不一定。因為getView是回調用的,什麼時候建立是由系統決定的(它很可能會提早建立,原因前面我說過了)。
比如滾屏造成有一行出了屏,有一行新的入了屏,那麼,系統會將出了屏的View做為參數(注意getView的第二個參數)調用getView,期望你將 出屏的View改造成入屏的View(這隻需要更新一下介面顯示即可,不需要再new View,這就是我在前面某一貼裡面跟你說的了——最佳化),如果每次都new,是很不負責的。
當然,上面只最佳化策略的一種,不排除還有其它策略,這要看google怎麼設計的了。
比如滾屏造成有一行出了屏,有一行新的入了屏
這個時候 新得到的view的 position 就會又充0計算
比如有2行進入的螢幕 那麼position 就是0~1了
所以列印就是 先列印0~5 然後你拖地列印0~1