19

Ho cercato attraverso tutte le risposte su che respinge una finestra di dialogo onTouchOutside, però, io sto usando DialogFragment nella mia applicazione. Come posso ottenere il licenziamento del DialogFragment quando l'utente fa clic all'esterno della regione DialogFragment.respingere DialogFragment (non Dialog) onTouchOutside

Ho esaminato dialogo s' source code per setCanceledOnTouchOutside

public void setCanceledOnTouchOutside(boolean cancel) { 
    if (cancel && !mCancelable) { 
     mCancelable = true; 
    } 

    mCanceledOnTouchOutside = cancel; 
} 

C'è un'altra funzione che può essere interessante che è isOutOfBounds

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

ma non sono riuscito a capire un modo per utilizzarli per DialogFragment

Oltre a questi ho esaminato lo stato dell'applicazione con hierarchyviewer e come ho capito, posso vedere solo la regione della finestra e non la parte outsied di essa (intendo la parte restante del schermo dopo DialogFragment).

si può suggerire un modo di attuazione del presente setCanceledOnTouchOutside per DialogFragment e, se possibile, con un codice di esempio?

risposta

34

La risposta è piuttosto semplice:

MyDialogFragment fragment = new MyDialogFragment(); // init in onCreate() or somewhere else 
... 
if (fragment.getDialog() != null) 
    fragment.getDialog().setCanceledOnTouchOutside(true); // after fragment has already dialog, i. e. in onCreateView() 

Vedi http://developer.android.com/reference/android/app/DialogFragment.html#setShowsDialog%28boolean%29 per maggiori informazioni su finestre di dialogo in DialogFragments.

+0

'DialogFragment' non ha un metodo chiamato' setCanceledOnTouchOutside() '' Dialog' ha. Si prega di leggere attentamente la domanda. –

+12

Sopra la risposta non implica che ha. 'DialogFragment' ha il metodo' getDialog() 'che restituisce' Dialog' quale metodo HAS 'setCanceledOnTouchOutside()'. Si prega di leggere attentamente la risposta. –

+3

Oh uomo .. per favore sii più descrittivo .. Se puoi modificare la risposta, posso prevederlo. L'ho chiamato all'interno di 'onCreateView()' di una implementazione personalizzata di 'DialogFragment' e funziona bene. Grazie. –

10

Nella maggior parte dei casi, getDialog() è nullo, poiché non lo si otterrà immediatamente dopo aver creato una nuova istanza della finestra di dialogo.

Come suggerito sopra onViewCreated è anche né corretto per DialogFragment in particolare quando si utilizza android.support.v4.app.DialogFragment.

Il sotto funziona bene, come è posizionato sul onCreateView:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    if (getDialog() != null) { 
     getDialog().setCanceledOnTouchOutside(true); 
    } 
    return super.onCreateView(inflater, container, savedInstanceState); 
} 
+1

Dovrebbe essere la risposta accettata – Kibi

+0

Sostituire questo metodo in DialogFragment. Ciò non era chiaro inizialmente poiché è comunemente sovrascritto in Fragments. – Ivan

4

Perché non basta ignorare onCreateDialog e basta impostare lì. In questo modo non è necessario verificare la nullità della chiamata getDialog() per tutto il tempo.

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) { 
    Dialog d = super.onCreateDialog(savedInstanceState); 
    d.setCanceledOnTouchOutside(false); 
    return d; 
} 
0

ho risposto ad un'altra domanda, ma la risposta è più appropriato per questo problema, My solution.Solo per breve qui, ho semplicemente implementato onTouch() di DialogFragment di getView() e controllato i limiti di tocco.