2017-03-15 1 views
2

Ich habe ein benutzerdefiniertes Dialogfeld, das im Prinzip funktioniert, es wird jedoch nur dann ausgeblendet, wenn Sie weit vom Dialogfeld entfernt klicken. Wenn ich sehr nah an den Dialog klicke, aber immer noch außerhalb (z. B. 30px von der Kante), passiert nichts ... der Dialog wird nicht geschlossen.dialogFragment wird nicht geschlossen, wenn man nahe an die Kante klickt

Ich sehe, dass dies auch auf einem grundlegenden alertDialog auftritt, der keine Anpassung verwendet. Soweit ich das beurteilen kann, ist dies eine Standard-Android-Sache. Liege ich falsch? Gibt es einen Grund dafür?

enter image description here

Es ist eine Eigenschaft .setCanceledOnTouchOutside(); Änderungen, die sich auf das Klicken bei entferntem Klicken auswirken, wie erwartet, haben jedoch keinen Einfluss auf die oben beschriebene Situation.

Die Dialogklasse:

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; 
    } 

} 

Der Dialog Layout:

<?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> 

Funktion in meiner Tätigkeit Aufruf Dialog:

private void showFiltersDialog() { 

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

} 
+0

Update: OP wurde ein beschreibendes Bild hinzugefügt. Ich habe auf meinem echten Gerät getestet, und es ist genau wie der Emulator. Auch, hat ein neues Projekt mit nur einem grundlegenden alertDialog, und das gleiche Problem existiert. Ist es ein Problem? – MarsAndBack

+0

Hast du gerade versucht setCancelable? https://developer.android.com/reference/android/app/DialogFragment.html#setCancelable(boolean) –

+0

Ich habe versucht, SetCancelable zu wechseln, aber es scheint keine Auswirkungen auf das Klicken-außerhalb-zu-entlassen haben. Unabhängig davon, in OP, kann ich den Dialog schließen ... nur nicht durch Klicken auf den Rand des Dialogs. – MarsAndBack

Antwort

3

Ich war selbst mit diesem Problem konfrontiert, also habe ich den Quellcode durchforstet. Stellt sich heraus, es ist absichtlich Verhalten und heißt "TouchSlop". Es ist in ViewConfiguration definiert:

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

Der säumige Code ist in der Window-Klasse:

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

Welche ruft dann:

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)); 
    } 

Der Wert davon kommt aus:

/** 
    * 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; 

Ich kann keine Möglichkeit finden, dieses Verhalten zu überschreiben oder den Slop-Wert zu ändern. Ich denke, die einzige Option wäre, einen Vollbilddialog mit einem transparenten Hintergrund und einem manuellen Klick-Handler zu implementieren. Ich habe entschieden, dass es keine gute Idee ist, das Standardverhalten des Systems zu überschreiben, also werde ich es nicht implementieren.

+0

Wow, tolle Sachen. Wenn ich eine Chance habe, probiere ich die Fullscreen-Dialogmethode aus und versuche, sie so aussehen zu lassen, als wäre es ein normaler Dialog. – MarsAndBack

Verwandte Themen