实现BottomSheetDialog效果的Activity

45 阅读1分钟

前情提要: 原来的页面为普通的activity,业务已经成熟。但是最新的UI需要修改成BottomSheetDialog半模态样式。而用BottomSheetDialog实现代价较大,所以改用Activity实现。

改造过程: 分析BottomSheetDialog实现方式。

分析主要依赖CoordinatorLayout 及com.google.android.material.bottomsheet.BottomSheetBehavior

实现结果: xml布局

activity_bottom_sheet.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/design_bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bottom_sheet_bg"
        app:behavior_fitToContents="false"
        app:behavior_hideable="true"
        app:behavior_skipCollapsed="true"
        app:layout_behavior="@string/bottom_sheet_behavior">


    </FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

BottomSheetActivity.java

public class BottomSheetActivity extends AppCompatActivity {
    protected FrameLayout mBottomSheet;
    protected BottomSheetBehavior mBehavior;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        //改造入场动画
        overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
        //设置状态栏颜色
        setStatusBarTransparent();
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
    }

    private void setStatusBarTransparent() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            );
            getWindow().setStatusBarColor(0x00000000);
            getWindow().setNavigationBarColor(getColor(R.color.bottom_sheet_bg));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                getWindow().setNavigationBarDividerColor(getColor(R.color.bottom_sheet_bg));
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    @Override
    public void setContentView(View view) {
        super.setContentView(view);
    }

    @Override
    public void setContentView(int layoutResID) {
        View contentView = getLayoutInflater().inflate(layoutResID, null);
        View rootView = getLayoutInflater().inflate(R.layout.activity_bottom_sheet, null);
        mBottomSheet = rootView.findViewById(R.id.design_bottom_sheet);
        mBottomSheet.addView(contentView);
        mBehavior = BottomSheetBehavior.from(mBottomSheet);
        mBehavior.setExpandedOffset(getStatusBarHeight(this));
        mBehavior.setSkipCollapsed(true);
        mBottomSheet.setPadding(0, 0, 0, getStatusBarHeight(this));
        mBottomSheet.post(new Runnable() {
            @Override
            public void run() {
                BottomSheetUtils.setBottomSheetAnimationDuration(BottomSheetActivity.this,mBehavior,700);
                mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        });
        mBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                    BottomSheetActivity.super.finish();
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }

        });
        super.setContentView(rootView);
    }

    public static int getStatusBarHeight(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    @Override
    public void finish() {
        if (mBehavior != null) {
            mBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
        }
        overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
    }
}

fade_in.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fromAlpha="0.0"
    android:toAlpha="1.0" />

fade_out.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fromAlpha="1.0"
    android:toAlpha="0.0" />

使用方式*

1.直接继承BottomSheetActivity

注意

1.在contentview中滑动的view必须是继承nestscroll,不然会引起滑动冲突,支持recycleview但不支持listview。