2017-03-15 69 views
2

我有一個基本上可以工作的自定義dialogFragment,但是如果您單擊(即點擊)遠離對話框,它只會被解散。如果我點擊非常靠近對話框,但仍然在外面(例如距邊緣30px),則沒有任何反應......對話框不會消失。dialogFragment在點擊接近邊緣時不會消失

即使在不使用自定義的基本alertDialog中,也會發生這種情況。據我所知,這是一個標準的Android事情。我錯了嗎?這有什麼原因嗎?

enter image description here

有一個屬性.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"); 

} 
+0

更新:向OP添加了描述性圖像。我已經在我的真實設備上進行了測試,它就像模擬器一樣。此外,只用一個基本的alertDialog做了一個新項目,存在同樣的問題。這是一個問題嗎? – MarsAndBack

+0

你剛試過setCancelable? https://developer.android.com/reference/android/app/DialogFragment.html#setCancelable(boolean) –

+0

我試過切換setCancelable,但它似乎沒有影響點擊外部到解僱。無論如何,在OP中,我可以關閉對話框......只需點擊靠近對話框邊緣即可。 – MarsAndBack

回答

3

我自己一直在面對這個問題,所以做了一些挖掘源代碼的工作。結果是有意的行爲,被稱爲「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值。我認爲唯一的選擇是用透明背景和手動點擊處理程序來實現全屏對話框。我已經決定,我的應用重寫默認系統行爲並不是一個好主意,所以我不會實現它。

+0

哇,好東西。當我有機會的時候,我會嘗試全屏對話方法,並嘗試在視覺上使它看起來像是一個常規對話框。 – MarsAndBack