I'm trying to create a activity which I can alter the background alpha.
Here's what I got:
layout.xml
<FrameLayout 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"
android:background="@android:color/transparent">
<com.liuguangqiang.swipeback.SwipeBackLayout
android:id="@+id/swipeback_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<FrameLayout
android:layout_gravity="center"
android:id="@+id/previewer_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.liuguangqiang.swipeback.SwipeBackLayout>
</FrameLayout>
style.xml:
<style name="AppTheme" parent="AppTheme.Base"/>
<style name="CustomStyle" parent="AppTheme">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
AndroidManifest.xml
<activity
android:name=".activity.TheActivity"
android:screenOrientation="portrait"
android:theme="@style/CustomStyle"/>
And inside activity's onCreate
I setup the swipeback
layout and put a listener to alter the background alpha while pulling:
swipebackLayout.setDragEdge(SwipeBackLayout.DragEdge.BOTTOM);
swipebackLayout.setEnableFlingBack(true);
swipebackLayout.setEnablePullToBack(true);
swipebackLayout.setOnPullToBackListener(new SwipeBackLayout.SwipeBackListener() {
@Override
public void onViewPositionChanged(float fractionAnchor, float fractionScreen) {
float alpha = (1 - fractionAnchor) * 255;
swipebackLayout.getBackground().setAlpha((int) alpha);
}
});
Here's the problem:
On Kitkat devices, this works perfectly: When you pulling the layout, it will alter the alpha simultaneously to change from completely black to transparent.
However, on Lollipop devices, this effect only works at the first time. The second time you open the same activity the alpha is been reset to 0 (transparent) at beginning, and I must explicitly set the background alpha in onCreate
each time(use the one-line-code attached below).
Why is that happening? Since the activity is finished properly and been created from fresh each time, why the alpha is 255 at the first time then in the second time creation it magically becomes 0?
// Window background is transparent, so we need to set alpha to opaque when creating the activity, without this line, lollipop devices will have a complete transparent background next time you launch the activity
swipebackLayout.getBackground().setAlpha(255);
// ------------
When you obtain a Drawable
for the first time, the Android resource framework retains a reference in a process-local cache. As a result, any modifications that you perform (e.g. any setZzz()
call) will also modify the version in the cache.
To avoid accidentally modifying the cached version, you should always call mutate()
at least once on a Drawable
before calling any setZzz()
methods.
Calling mutate()
more than once is a no-op, so you can just prefix all setter calls with it.
So in this particular case, you would want:
swipebackLayout.getBackground().mutate().setAlpha(...);
Note: There is no guarantee that failing to call mutate()
will allow you to modify the cached version, or that a call to getDrawable()
will always return the cached version. However, calling mutate()
is always guaranteed to allow you to safely modify a drawable.