如何更改 BottomSheetDialogFragment 的 BottomSheetBehavior?

huangapple go评论92阅读模式
英文:

How to change BottomSheetBehavior of BottomSheetDialogFragment?

问题

我有一个模态的 BottomSheetDialog。当前的默认行为是,当我将对话框向下拖动一半时,它会关闭。例如,假设对话框的值从0.0(折叠)到1.0(展开)。因此,当用户将其向下拖动到0.5时,它会折叠。但我想要的行为是,在我将对话框向下拖到0.8并放开手指时,关闭对话框。我如何实现这种行为,有什么办法吗?

另外,我认为只有在我使用拖动按钮(大多数情况下是简单的 ImageView)拖动对话框时,才允许对话框关闭。

因此,我希望的是,当用户稍微向下移动对话框(拖动)时,关闭对话框。

因此,我当前的代码是:

public class FiltersBottomSheet extends BottomSheetDialogFragment {

    private FragmentFilterBinding binding;

    public FiltersBottomSheet() {}

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_filter, container, false);
        View view = binding.getRoot();

        // 我在使用数据绑定
        // 这里有一些逻辑,但现在你不需要它 :)

        return view;
    }
    
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        view.getViewTreeObserver()
                .addOnGlobalLayoutListener(() -> {
                    BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
                    LinearLayout bottomSheet = dialog.findViewById(R.id.bottom_frame);

                    if (bottomSheet != null) {
                        BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
                        behavior.setState(BottomSheetBehavior.STATE_EXPANDED);

                        behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                            @Override
                            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                                //Log.d("Tag___1", "NewState: " + newState);
                            }

                            @Override
                            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                                //Log.d("Tag___1", "Offset: " + slideOffset);
                            }
                        });
                    }
                });
    }
}

首先,我认为 onSlide() 可能有助于我,但是... 这个方法仅在用户展开或折叠对话框时调用。例如,当用户触摸对话框并开始向下拖动时,onSlide() 方法不会被调用。您可以看到我在上面调用了 view.getViewTreeObserver(),我尝试将 onTouchListener 添加到此视图。问题在于,当用户在移动对话框后松开手指时,MotionEvent.ACTION_UP 没有被调用。有什么想法吗?谢谢。

英文:

I have a modal BottomSheetDialog. Current and the default behavior of the dialog is, when I drag the dialog down by half, it dismisses. E.g assume the dialog value is from 0.0 (Collapsed) to 1.0 (Expanded). So when user drags it down to 0.5, it collapses. But the behavior that I want, is to dismiss the dialog when I drag the dialog down to 0.8 and take off my finger. How can I achieve this behavior, is there any way???

Also, I think it would be great to allow the dialog dismiss only when I drag it with any drag button (most of cases it's a simple ImageView).

So what I want is to dismiss the dialog, when user moves the dialog(drags) a little bit down.

So my current code is:

public class FiltersBottomSheet extends BottomSheetDialogFragment {
private FragmentFilterBinding binding;
public FiltersBottomSheet() {}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_filter, container, false);
View view = binding.getRoot();
// I'm using data binding
// There is a little logic, but now you don't need it :)
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.getViewTreeObserver()
.addOnGlobalLayoutListener(() -> {
BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
LinearLayout bottomSheet = dialog.findViewById(R.id.bottom_frame);
if (bottomSheet != null) {
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
//Log.d("Tag___1", "NewState: " + newState);
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
//Log.d("Tag___1", "Offset: " + slideOffset);
}
});
}
});
}
}

So first of all I thought that onSlide() can help me, but... This method called only when user expands or collapses the dialog. So e.g. when user touches the dialog and starts to drag it down, the onSlide() method doesn't called. Also you see above I called view.getViewTreeObserver(), I've tried to add onTouchListener to this view. And the problem is here, that the MotionEvenet.ACTION_UP is not calling when the user removes his finger after moving the dialog. So any idea? Thank you.

答案1

得分: 4

@Override
public void onViewCreated(@NotNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.getViewTreeObserver()
            .addOnGlobalLayoutListener(() -> {
                BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
                if (dialog != null) {
                    FrameLayout bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
                    if (bottomSheet != null) {
                        BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
                        behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                        behavior.setSkipCollapsed(true);
                        behavior.setHideable(false);
                    }
                }
            });
}

This will help you to set the state as expanded and disable hiding, and you can also specify a custom size for expansion.

英文:

If you want to modify the bottom sheet dialog behaviour in your bottom dialog fragment use this:

@Override
public void onViewCreated(NotNull@ View view, Nullable@ Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState)
view.getViewTreeObserver()
.addOnGlobalLayoutListener(() -> {
BottomSheetDialog dialog =(BottomSheetDialog) getDialog ()
if (dialog != null) {
FrameLayout bottomSheet = dialog.findViewById (R.id.design_bottom_sheet)
if (bottomSheet != null) {
BottomSheetBehavior behavior = BottomSheetBehavior.from (bottomSheet)
behavior.setState(BottomSheetBehavior.STATE_EXPANDED)
behavior.setSkipCollapsed(true)
behavior.setHideable(false)
}
}
})
}

This will help you to state expanded and hideable false and you can put custom size to be expanded also.

答案2

得分: 2

我认为您可以自定义属性behavior_halfExpandedRatio,还可以在滑动时自定义回调:

val bottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() {
    
    override fun onStateChanged(bottomSheet: View, newState: Int) {
        // 在新状态下执行某些操作
    }

    override fun onSlide(bottomSheet: View, slideOffset: Float) {
        // 在滑动偏移时执行某些操作
    }
}
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallback)
英文:

I think you can customize the attribute behavior_halfExpandedRatio and you can also customize the callbacks when sliding:

val bottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
// Do something for new state
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
// Do something for slide offset
}
}
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallback)

huangapple
  • 本文由 发表于 2020年4月4日 19:20:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/61027310.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定