【问题标题】:dialogFragment doesn't dismiss when clicking close to it's edge当点击靠近它的边缘时,dialogFragment 不会关闭
【发布时间】:2017-03-15 00:00:58
【问题描述】:

我有一个自定义的 dialogFragment,它基本上可以工作,但是只有在远离对话框的地方单击(即点击)它才会消失。如果我在非常靠近对话框的位置单击,但仍在外部(例如距离边缘 30 像素),则不会发生任何事情...对话框不会关闭。

我发现即使在没有自定义的基本 alertDialog 上也会发生这种情况。据我所知,这是标准的 Android 设备。我错了吗?有什么原因吗?

有一个属性 .setCanceledOnTouchOutside();更改确实会按预期影响有效的点击远处解雇,但对上述接近边缘的情况没有影响。

对话框类:

public class Filters_DialogFragment extends DialogFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.filters_dialog, container, false);
        getDialog().setTitle("Simple Dialog");

        // FYI, this has no affect on clicking very close to the dialog edge.
        getDialog().setCanceledOnTouchOutside(true);

        return rootView;
    }

}

对话框布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#333333">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="FILTERS"
        android:textColor="#ffffff" />

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

我的活动中调用对话框的函数:

private void showFiltersDialog() {

    FragmentManager fm = getSupportFragmentManager();
    Filters_DialogFragment dialogFragment = new Filters_DialogFragment();
    dialogFragment.show(fm, "Sample Fragment");

}

【问题讨论】:

  • 更新:向 OP 添加了描述性图像。我已经在我的真实设备上进行了测试,它就像模拟器一样。此外,做了一个只有基本警报对话框的新项目,并且存在同样的问题。有问题吗?
  • 我试过切换 setCancelable,但它似乎对点击外部关闭没有影响。无论如何,在 OP 中,我可以关闭对话框......只是不能通过单击靠近对话框的边缘。

标签: android dialogfragment


【解决方案1】:

我自己也遇到过这个问题,所以我也对源代码进行了一些挖掘。原来这是故意行为,被称为“touchSlop”。它在 ViewConfiguration 中定义:

https://developer.android.com/reference/android/view/ViewConfiguration.html#getScaledWindowTouchSlop()

违规代码在 Window 类中:

public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
        if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
                && isOutOfBounds(context, event) && peekDecorView() != null) {
            return true;
        }
        return false;
    }

然后调用:

private boolean isOutOfBounds(Context context, MotionEvent event) {
        final int x = (int) event.getX();
        final int y = (int) event.getY();
        final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
        final View decorView = getDecorView();
        return (x < -slop) || (y < -slop)
                || (x > (decorView.getWidth()+slop))
                || (y > (decorView.getHeight()+slop));
    }

其中的值来自:

/**
     * Distance in dips a touch needs to be outside of a window's bounds for it to
     * count as outside for purposes of dismissing the window.
     */
    private static final int WINDOW_TOUCH_SLOP = 16;

我找不到任何方法来覆盖此行为或更改 slop 值。我认为唯一的选择是实现具有透明背景和手动单击处理程序的全屏对话框。我决定让我的应用覆盖默认系统行为不是一个好主意,所以我不打算实现它。

【讨论】:

  • 哇,好东西。如果有机会,我会尝试全屏对话框的方法,并尝试在视觉上让它看起来像是一个普通的对话框。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多