Android如何实现背景模糊并点击模糊区域关闭上层Fragment
实现方案
1. 前置布局修改
首先修改FragmentA布局中的容器属性,将filter_pop_up_frame_lyt的高度改为匹配父布局,保证上层Fragment可以铺满屏幕:
<FrameLayout android:id="@+id/filter_pop_up_frame_lyt" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/filter_container_lyt" android:elevation="5dp"> </FrameLayout>
2. 上层Fragment布局调整
修改要显示的上层Fragment的根布局,新增全屏透明背景层、拦截点击穿透,拆分背景区域和内容区域:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/linear_layout_root_price_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:focusable="true" android:background="#88000000" android:orientation="vertical"> <!-- 全屏透明背景区域,用于点击关闭 --> <View android:id="@+id/blur_bg_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <!-- 原内容区域 --> <LinearLayout android:id="@+id/content_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/filter_bg_round_corner" android:orientation="vertical"> <!-- 此处保留你原来的所有内容代码,不用修改 --> </LinearLayout> </LinearLayout>
3. 背景模糊效果实现
分为两种方案,可根据需求选择:
方案1:简易半透明背景(兼容全版本,无性能损耗)
直接用上面布局里的半透明黑色背景#88000000即可,透明度可以自行调整,前两位是十六进制透明度(00完全透明,FF完全不透明),可以满足大部分场景下层内容隐约可见的需求。
方案2:实时毛玻璃模糊效果
如果需要真实的毛玻璃效果,用Android原生RenderScript实现:
- 在app模块
build.gradle中开启RenderScript支持:
android { defaultConfig { renderscriptTargetApi 33 renderscriptSupportModeEnabled true } }
- 添加模糊工具类:
import android.content.Context import android.graphics.Bitmap import android.renderscript.Allocation import android.renderscript.Element import android.renderscript.RenderScript import android.renderscript.ScriptIntrinsicBlur object BlurUtils { fun blurBitmap(context: Context, source: Bitmap, radius: Float = 15f): Bitmap { val renderScript = RenderScript.create(context) val input = Allocation.createFromBitmap(renderScript, source) val output = Allocation.createTyped(renderScript, input.type) val script = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)) script.setRadius(radius.coerceAtMost(25f)) script.setInput(input) script.forEach(output) output.copyTo(source) renderScript.destroy() return source } }
- 在上层Fragment的
onViewCreated中生成模糊背景:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 获取下层FragmentA的根视图截图 val rootView = requireParentFragment().requireView() rootView.isDrawingCacheEnabled = true val sourceBitmap = Bitmap.createBitmap(rootView.drawingCache) rootView.isDrawingCacheEnabled = false // 模糊处理 val blurBitmap = BlurUtils.blurBitmap(requireContext(), sourceBitmap) // 设置为上层背景 view.setBackgroundDrawable(BitmapDrawable(resources, blurBitmap)) // 再叠加一层半透明黑,提升内容对比度,可省略 view.background.alpha = 200 }
4. 点击模糊区域关闭功能实现
在上层Fragment的onViewCreated中添加点击事件:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 点击模糊背景关闭 view.findViewById<View>(R.id.blur_bg_view).setOnClickListener { parentFragmentManager.popBackStack() } // 拦截内容区域点击,防止触发关闭 view.findViewById<View>(R.id.content_layout).setOnClickListener {} }
注意:在FragmentA中添加上层Fragment时,一定要添加到回退栈:
parentFragmentManager.beginTransaction() .add(R.id.filter_pop_up_frame_lyt, YourUpperFragment()) .addToBackStack(null) .commit()
内容的提问来源于stack exchange,提问作者I'm Coder
相关产品推荐
相关产品推荐

