I can control the ListView's fading edge through the property android:cacheColorHint. This is all good and very convenient. I can set both the colour and the strenght ( by adding alpha to the colour property )
Logically I would expect it to be 开发者_如何学Goequally simple to control the fading edge of a scrollView as well however it is not. There are a few solutions however they are not ideal.
- Extend the ScrollView and override the getSolidColor() function. This allows me to change the color to whatever I want however the alpha value of the color will be ignored so if I use 0x33000000 it will always be a gradient from full black to full transparent.
- Use the ScrollViews background property. This gives me both control of the color and the intensity ( through the alpha value ) however it also sets the background to the color of the fade which might not be what I want.
My question is if anyone has found a better solution to this. A solution that would give you control of both color and intensity of the ScrollViews fading edge without using the background property.
Your solution #2 (use ScrollView background property) works because you can overcome the one problem that you mentioned (you might want the background and fade colors to be different). [Answer based on Android 1.6 donut-release2]
I think this is what you are attempting, where the edges fade to 0x8800FF00 and the general background is different (in this case it's 0x88FFFFFF on top of the 0x8800FF00 just to show that alpha is relevant) and child backgrounds are different still (the buttons and the black and white text sections are opaque):
Notice the background settings in the layout file:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ScrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#8800FF00"
>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#88FFFFFF"
>
<Button android:text="Hello no style" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
...
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:background="@android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:textColor="#80ffffff" android:text="#80ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
...
</LinearLayout>
<LinearLayout
android:background="@android:color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:textColor="#80ffffff" android:text="#80ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
...
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
The way View.java applies the edges is to first draw the ScrollView's background (if there is one) and then, in an offscreen bitmap (call it ContentBitmap), draw the ScrollView's content and apply a LinearGradient with DST_OUT xfermode to the edges. DST_OUT uses only the alpha from the source, and the LinearGradient/DST_OUT makes the edges of the ContentBitmap gradually more transparent and dark. View.draw() then merges the ContentBitmap to the main canvas via SRC_OVER xfermode, which lets the previously drawn background show through the translucent ContentBitmap pixels.
Notes
As for adroid:colorCacheHint
, it is a value that ListView (but not ScrollView) uses to override View.getSolidColor()
, which, in turn, causes View.draw()
to call View.ScrollabilityCache.setFadeColor()
and create a SRC_OVER LinearGradient instead of a DST_OUT one. setFadeColor()
forces the gradient to range from hintColor|0xFF000000
to 0x0
. Note also that SRC_OVER doesn't make a result pixel in ContentBitmap any more transparent than it already is, so this solid-color variation of fade is really a paint-the-fade-effect-on-top instead of fade-the-pixels-with-transparency.
The fading edge feature in View.java is private; to customize it is to reimplement it in your subclass.
I tried the same background settings for a ListView (as obtained from a ListActivity), but it appeared that the fade got applied right through the backgrounds. A puzzle for another day.
精彩评论