Android Lollipop 将布局的 alpha 重置为透明
Android Lollipop reset layout's alpha to transparent
我正在尝试创建一个 activity,我可以更改背景 alpha。
这是我得到的:
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"/>
在 activity 的 onCreate
中,我设置了 swipeback
布局,并在拉动时放置了一个监听器来改变背景 alpha:
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);
}
});
这是问题所在:
在 Kitkat 设备上,这非常有效:当您拉动布局时,它会同时改变 alpha,从全黑变为透明。
但是,在 Lollipop 设备上,此效果仅在第一次使用时有效。第二次打开相同的 activity 时,alpha 在开始时被重置为 0(透明),我必须每次都在 onCreate
中明确设置背景 alpha(使用附带的单行代码下面)。
问题
为什么会这样?由于 activity 正确完成并且每次都是从新创建的,为什么 alpha 第一次是 255 然后在第二次创建时它神奇地变成了 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);
// ------------
当您第一次获得 Drawable
时,Android 资源框架会在进程本地缓存中保留一个引用。因此,您执行的任何修改(例如任何 setZzz()
调用)也会修改缓存中的版本。
为避免意外修改缓存版本,在调用任何 setZzz()
方法之前,您应该始终在 Drawable
上至少调用一次 mutate()
。
多次调用 mutate()
是空操作,因此您可以在所有 setter 调用前加上它。
所以在这种特殊情况下,您需要:
swipebackLayout.getBackground().mutate().setAlpha(...);
注意: 无法保证调用 mutate()
失败将允许您修改缓存版本,或者调用 getDrawable()
将允许您修改缓存版本始终 return 缓存版本。但是,调用 mutate()
始终保证允许您安全地修改可绘制对象。
我正在尝试创建一个 activity,我可以更改背景 alpha。
这是我得到的:
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"/>
在 activity 的 onCreate
中,我设置了 swipeback
布局,并在拉动时放置了一个监听器来改变背景 alpha:
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);
}
});
这是问题所在:
在 Kitkat 设备上,这非常有效:当您拉动布局时,它会同时改变 alpha,从全黑变为透明。
但是,在 Lollipop 设备上,此效果仅在第一次使用时有效。第二次打开相同的 activity 时,alpha 在开始时被重置为 0(透明),我必须每次都在 onCreate
中明确设置背景 alpha(使用附带的单行代码下面)。
问题
为什么会这样?由于 activity 正确完成并且每次都是从新创建的,为什么 alpha 第一次是 255 然后在第二次创建时它神奇地变成了 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);
// ------------
当您第一次获得 Drawable
时,Android 资源框架会在进程本地缓存中保留一个引用。因此,您执行的任何修改(例如任何 setZzz()
调用)也会修改缓存中的版本。
为避免意外修改缓存版本,在调用任何 setZzz()
方法之前,您应该始终在 Drawable
上至少调用一次 mutate()
。
多次调用 mutate()
是空操作,因此您可以在所有 setter 调用前加上它。
所以在这种特殊情况下,您需要:
swipebackLayout.getBackground().mutate().setAlpha(...);
注意: 无法保证调用 mutate()
失败将允许您修改缓存版本,或者调用 getDrawable()
将允许您修改缓存版本始终 return 缓存版本。但是,调用 mutate()
始终保证允许您安全地修改可绘制对象。