美文网首页APP & program
关于安卓底部dialogfragment封装

关于安卓底部dialogfragment封装

作者: motosheep | 来源:发表于2022-11-28 14:40 被阅读0次

    上文封装了一个普通的dialogfragment
    dialog fragment
    是基于Android X DialogFragment 进行封装的。

    本文将会基于BottomSheetDialogFragment进行封装。
    对比普通的DialogFragment进行封装,不同的是,BottomSheetDialogFragment是专门用于底部弹窗进行封装的。
    它有以下特点:
    (一)拥有出场进场的动画(官方自带动画属性)
    (二)可扩展BottomViewDialog,和BottomSheetBehavior实现拖拽相关操作,实现下拉关闭弹窗!

    注意事项:
    (1)适配软键盘弹出,需要通过dialog的window设置键盘参数,具体代码如下:

    getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
    

    注意,如果要通过getActivity()设置外层的window键盘参数模式,代码同上,使用键盘监听的方法会失效!具体原因是因为监听不到键盘弹出事件了!
    (2)内部布局为recyclerview时,存在滑动冲突,需要手动设置以下代码,适配欢动冲突事件:

    rvContent.getRecyclerView().setHasFixedSize(true);
    rvContent.getRecyclerView().setNestedScrollingEnabled(false);
    

    原理和recyclerview适配scrollview时一致的。

    最后放出全部代码:

    package com.jeagine.cloudinstitute2.view.dialogfragment;
    
    import android.app.Dialog;
    import android.content.DialogInterface;
    import android.graphics.Color;
    import android.graphics.drawable.ColorDrawable;
    import android.os.Bundle;
    import android.view.Gravity;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.FrameLayout;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.coordinatorlayout.widget.CoordinatorLayout;
    
    import com.google.android.material.bottomsheet.BottomSheetBehavior;
    import com.google.android.material.bottomsheet.BottomSheetDialog;
    import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
    import com.jeagine.cloudinstitute2.R;
    import com.jeagine.yidian.util.SystemBarUtils;
    
    import io.reactivex.rxjava3.disposables.CompositeDisposable;
    import io.reactivex.rxjava3.observers.DisposableObserver;
    
    /**
     * FileName: BaseDialogFragment
     * Author: lzt
     * Date: 2022/8/30 17:33
     * change by lzt 20221020 抽离默认宽高初始化方法
     */
    public abstract class BaseBottomDialogFragment extends BottomSheetDialogFragment {
    
        private int DEFAULT_WIDTH = WindowManager.LayoutParams.MATCH_PARENT;//宽
        private int DEFAULT_HEIGHT = WindowManager.LayoutParams.MATCH_PARENT;//高
        private int DEFAULT_GRAVITY = Gravity.BOTTOM;//位置
    
        private boolean mCancelable = true;//默认可取消
        private boolean mCanceledOnTouchOutside = true;//默认点击外部可取消
    
        private BottomSheetBehavior<FrameLayout> bottomSheetBehavior;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View mView = inflater.inflate(getLayoutId(), container, false);
            initViews(mView);
    //        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
            if (getDialog() != null && getDialog().getWindow() != null) {
                getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
            }
            return mView;
        }
    
        @Override
        public void onDestroyView() {
            clearObserver();
            super.onDestroyView();
        }
    
        @NonNull
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            BottomSheetDialog mDialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
            if (null != mDialog) {//初始化
                mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                mDialog.setCanceledOnTouchOutside(mCanceledOnTouchOutside);
                mDialog.setCancelable(mCancelable);
                Window window = mDialog.getWindow();
                if (null != window) {
                    window.getDecorView().setPadding(0, 0, 0, 0);
                    window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
                    WindowManager.LayoutParams lp = window.getAttributes();
                    lp.width = defWidth();
                    lp.height = defHeight();
                    lp.gravity = DEFAULT_GRAVITY;
                    lp.windowAnimations = android.R.style.Animation_InputMethod;
                    window.setAttributes(lp);
                    window.setDimAmount(dimAmount());
                }
                mDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                    @Override
                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                        return !mCancelable;
                    }
                });
            }
            return mDialog;
        }
    
    
        @Override
        public void onStart() {
            super.onStart();
            initSlide();
        }
    
        /**
         * 初始化滑动交互
         */
        private void initSlide() {
            if (!canSlide()) {
                return;
            }
            try {
                if (getDialog() != null && getDialog() instanceof BottomSheetDialog) {
                    int peekHeight = getPeekHeight() -
                            SystemBarUtils.getStatusBarHeight(getContext());
                    BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
                    //把windows的默认背景颜色去掉,不然圆角显示不见
                    dialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackground(new ColorDrawable(Color.TRANSPARENT));
                    //获取dialog的根部局
                    FrameLayout bottomSheet = dialog.getDelegate().findViewById(R.id.design_bottom_sheet);
                    //获取根部局的LayoutParams对象
                    CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams();
                    layoutParams.height = peekHeight;
                    //修改弹窗的最大高度,不允许上滑(默认可以上滑)
                    bottomSheet.setLayoutParams(layoutParams);
                    bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
                    //peekHeight即弹窗的最大高度
                    bottomSheetBehavior.setPeekHeight(peekHeight);
                    //初始为展开状态
                    bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    //                bottomSheetBehavior.setHideable(false);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 弹窗高度
         * 子类可重写该方法返回peekHeight
         *
         * @return height
         */
        protected int getPeekHeight() {
            return getResources().getDisplayMetrics().heightPixels;
        }
    
        protected float dimAmount() {
            return 0.6f;
        }
    
        protected int defWidth() {
            return DEFAULT_WIDTH;
        }
    
        protected int defHeight() {
            return DEFAULT_HEIGHT;
        }
    
    
        /**
         * 能否滑动
         */
        protected boolean canSlide() {
            return true;
        }
    
        /**
         * 设置位置
         *
         * @param gravity
         */
        public void setGravity(int gravity) {
            DEFAULT_GRAVITY = gravity;
        }
    
        /**
         * 设置宽
         *
         * @param width
         */
        public void setWidth(int width) {
            DEFAULT_WIDTH = width;
        }
    
        /**
         * 设置高
         *
         * @param height
         */
        public void setHeight(int height) {
            DEFAULT_HEIGHT = height;
        }
    
        /**
         * 设置点击返回按钮是否可取消
         *
         * @param cancelable
         */
        public void setCancelable(boolean cancelable) {
            mCancelable = cancelable;
        }
    
        /**
         * 设置点击外部是否可取消
         *
         * @param canceledOnTouchOutside
         */
        public void setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
            mCanceledOnTouchOutside = canceledOnTouchOutside;
        }
    
        /**
         * 设置布局
         *
         * @return
         */
        protected abstract int getLayoutId();
    
        /**
         * 初始化Views
         *
         * @param v
         */
        protected abstract void initViews(View v);
    
    
        //rxjava release----------------------------
        private CompositeDisposable mDisposables = new CompositeDisposable();
    
    
        private void addObserver(DisposableObserver<?> disposableObserver) {
            mDisposables.add(disposableObserver);
        }
    
    
        private void removeObserver(DisposableObserver<?> disposableObserver) {
            if (mDisposables == null || disposableObserver == null) {
                return;
            }
            mDisposables.remove(disposableObserver);
        }
    
    
        private void clearObserver() {
            if (mDisposables != null) {
                mDisposables.clear();
            }
        }
    
    
        public abstract class BaseSafeObserver<T> extends DisposableObserver<T> {
    
            @Override
            protected void onStart() {
                super.onStart();
                addObserver(this);
            }
    
            @Override
            public void onNext(@NonNull T t) {
            }
    
            @Override
            public void onError(@NonNull Throwable e) {
                removeObserver(this);
            }
    
            @Override
            public void onComplete() {
                removeObserver(this);
            }
        }
    
    
        public void releaseResource() {
            clearObserver();
        }
        //rxjava release----------------------------
    
        /**
         * 能否向下滑动收起弹窗
         */
        protected void setCanSlide(boolean canSlide) {
    //        if (bottomSheetBehavior != null) {
    //            if (bottomSheetBehavior.isHideable() == canSlide) {
    //                return;
    //            }
    //            bottomSheetBehavior.setHideable(canSlide);
    //        }
        }
    
    }
    
    
    

    that's all-------------------------------------------------------------------------

    相关文章

      网友评论

        本文标题:关于安卓底部dialogfragment封装

        本文链接:https://www.haomeiwen.com/subject/klohfdtx.html