Android ListView(GridView) 滑動 拖動 背景爲黑色的解決辦法

Android ListView 滑動背景爲黑色的解決辦法

在Android中,ListView是最常用的一個控件,在做UI設計的時候,很多人希望能夠改變一下它的背景,使他能夠符合整體的UI設計,改變背景背很簡單只需要準備一張圖片然後指定屬性 android:background="@drawable/bg",不過不要高興地太早,當你這麼做以後,發現背景是變了,但是當你拖動,或者點擊list空白位置的時候發現ListItem都變成黑色的了,破壞了整體效果,如下圖所示:

 

 

 

 

 

 

 

 

 

 

這是爲什麼呢?

 

這個要從Listview的效果說起,默認的ListItem背景是透明的,而ListView的背景是固定不變的,所以在滾動條滾動的過程中如果 實時地去將當前每個Item的顯示內容跟背景進行混合運算,所以android系統爲了優化這個過程用,就使用了一個叫做 android:cacheColorHint的屬性,在黑色主題下默認的顏色值是#191919,所以就出現了剛纔的畫面,有一半是黑色的.

 

那怎麼辦呢?

 

如果你只是換背景的顏色的話,可以直接指定android:cacheColorHint爲你所要的顏色,如果你是用圖片做背景的話,那也只要將 android:cacheColorHint指定爲透明(#00000000)就可以了,當然爲了美化是要犧牲一些效率的。最後就不回出現上面所說的你 不想要的結果了!
自定義ListView行間的分割線

在Android平臺中系統控件提供了靈活的自定義選項,所有基於ListView或者說AbsListView實現的widget控件均可以通過下面的方法設置行間距的分割線,分割線可以自定義顏色、或圖片。

在ListView中我們使用屬性 android:divider="#FF0000" 定義分隔符爲紅色,當然這裏值可以指向一個drawable圖片對象,如果使用了圖片可能高度大於系統默認的像素,可以自己設置高度比如6個像素 android:dividerHeight="6px" ,Android開發網提示當然在Java中ListView也有相關方法可以設置。

 

1)點擊Item時無背景顏色變化
在xml文件中的ListView控件中加入如下屬性:
android:listSelector="@drawable/timer_list_selector"
在drawable中定義timer_list_selector的屬性值
timer_list_selector.xml中定義如下:
<?xml version="1.0" encoding="utf-8"?>
<selectorxmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"android:drawable="@android:color/transparent" />
</selector>
在values文件夾下的colors.xml中定義transparent如下:
<color name="transparent">#50000000</color>

2)設置Item之間無間隙
在xml文件中ListView控件中加入如下屬性:
android:divider="#00000000"
或者在javaCode中如下定義:
listView.setDividerHeight(0);

3)自定義的BaseAdapter中調用notifyDataSetChanged()方法會重新調用BaseAdaptergetView()方法。

用心的朋友應該會發現,listview中在設置了背景之後。會有些問題。

 

1.、listview在拖動的時候背景圖片消失變成黑色背景。等到拖動完畢我們自己的背景圖片才顯示出來。

 

2 、listview的上邊和下邊有黑色的陰影。

 

3、lsitview的每一項之間需要設置一個圖片做爲間隔。

 

針對以上問題 在listview的xml文件中設置一下語句。

 

問題1 有如下代碼結解決 android:scrollingCache="false"

 

問題2 用如下代碼解決:android:fadingEdge="none"
問題3 用如下代碼解決: android:divider="@drawable/list_driver" 其中 @drawable/list_driver 是一個圖片資源

 

 

 

總體如下

 

<ListView
android:id="@+id/myListView01"
android:layout_width="fill_parent"
android:layout_height="287dip"
android:fadingEdge="none"
android:divider="@drawable/list_driver"
android:scrollingCache="false"
android:background="@drawable/list">
</ListView>

 

 

Whyis my list black? An Android optimization

 

Posted by Romain Guy on 13 January 2009at 11:20 AM

 

 

ListViewis one of Android's most widely used widgets. It is rather easy to use, veryflexible and incredibly powerful. ListView can also bedifficult to understand at times.

One of the most common issues with ListView happens when you try to use a custom background. By default, likemany Android widgets, ListView has a transparent background which means yo can see through thedefault window's background, a very dark gray (#FF191919 withthe current dark theme.) Additionally, ListView enables the fadingedges by default, as you can see at the top of the followingscreenshot; the first text item gradually fades to black. This technique isused throughout the system to indicate that the container can be scrolled.

Android'sdefault ListView

The fade effect is implemented using acombination of Canvas.saveLayerAlpha()and the Porter-DuffDestination Out blending mode. This technique is similar to the oneexplained in Filthy Rich Clientsand various presentations. Unfortunately, things start to get ugly when you tryto use a custom background on the ListView or when youchange the window's background. The following two screenshots show what happensin an application when you change the window's background. The left image showswhat the list looks like by default and the right image shows what the list lookslike during a scroll initiated with a touch gesture:

Darkfade  Dark list

This rendering issue is caused by anoptimization of the Android framework enabled by default on all instances of ListView (for some reason, I forgot to enable it by default on GridView.) I mentioned earlier that the fade effect is implemented using aPorter-Duff blending mode. This implementation works really well but isunfortunately very costly and can bring down drawing performance by quite a bitas it requires to capture a portion of the rendering in an offscreen bitmap andthen requires extra blending (which implies readbacks from memory.)

Since ListView ismost of the time displayed on a solid background, there is no reason to go downthat expensive route. That's why we introduced an optimization called the"cache color hint." The cache color hint is an RGB color set bydefault to the window's background color, that is #191919 in Android's darktheme. When this hint is set, ListView (actually, itsbase class View) knows it will draw on a solid background and therefore replaces thexpensive saveLayerAlpha()/Porter-Duff rendering with a simple gradient. This gradient goes from fullytransparent to the cache color hint value and this is exactly what you see onthe image above, with the dark gradient at the bottom of the list. However,this still does not explain why the entire list turns black during a scroll.

As I said before, ListView has atransparent/translucent background by default, and so all default Androidwidgets. This implies that when ListView redraws itschildren, it has to blend the children with the window's background. Onceagain, this requires costly readbacks from memory that are particularly painfulduring a scroll or a fling when drawing happens dozen of times per second. Toimprove drawing performance during scrolling operations, the Android frameworkreuses the cache color hint. When this hint is set, the framework copies eachchild of the list in a Bitmap filled with the hint value (this assumes that another optimization,called scrolling cache, is not turned off.) ListView then blits these bitmaps directly on screen and because thesebitmaps are known to be opaque, no blending is required. And since the defaultcache color hint is #191919, you get a dark background behind each item during a scroll.

To fix this issue, all you have to do iseither disable the cache color hint optimization, if you use a non-solid colorbackground, or set the hint to the appropriate solid color value. This can bedome fromcode or preferably from XML, by using the android:cacheColorHint attribute. To disable the optimization, simply use the transparentcolor #00000000. The following screenshot shows a list with android:cacheColorHint="#00000000" set in the XML layout file:

fadeon a custom background

As you can see, the fade works perfectlyagainst the custom wooden background. I find the cache color hint feature interestingbecause it shows how optimizations can make developers' life more difficult insome situations. In this particular case, however, the benefit of the defaultbehavior outweighs the added complexity for the developer.

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章