Position de DialogFragment dans Android
j'ai un DialogFragment
pour afficher un View
comme un écran Popup.
La fenêtre apparaît toujours au milieu de l'écran.
Est-il un moyen de régler la position de la DialogFragment
fenêtre?
J'ai regardé dans le code source mais n'a pas pu trouver quoi que ce soit encore.
5 réponses
Essayez quelque chose comme ceci:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
getDialog().getWindow().setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
WindowManager.LayoutParams p = getDialog().getWindow().getAttributes();
p.width = ViewGroup.LayoutParams.MATCH_PARENT;
p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
p.x = 200;
...
getDialog().getWindow().setAttributes(p);
...
ou d'autres méthodes pour getDialog().getWindow()
.
assurez-vous de régler la position après avoir appelé set-content.
à droite, j'ai cogné la tête contre le mur pendant une heure ou deux avec ceci, avant de finalement obtenir DialogFragment
positionné comme je voulais.
Je m'appuie sur la réponse de Steelight ici. C'est l'approche la plus simple et la plus fiable que j'ai trouvée.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) {
Window window = getDialog().getWindow();
// set "origin" to top left corner, so to speak
window.setGravity(Gravity.TOP|Gravity.LEFT);
// after that, setting values for x and y works "naturally"
WindowManager.LayoutParams params = window.getAttributes();
params.x = 300;
params.y = 100;
window.setAttributes(params);
Log.d(TAG, String.format("Positioning DialogFragment to: x %d; y %d", params.x, params.y));
}
notez que params.width
et params.softInputMode
(utilisés dans la réponse de Steelight) ne sont pas pertinents à cet égard.
ci-dessous est un exemple plus complet. Ce dont j'avais vraiment besoin était d'aligner un fragment de dialogue "confirm box" à côté d'une vue "source" ou "parent", dans mon cas un bouton D'image.
j'ai choisi D'utiliser DialogFragment, au lieu de N'importe quel Fragment personnalisé, Parce qu'il vous donne des fonctionnalités de" dialogue " gratuitement (fermer dialogue lorsque l'utilisateur clique en dehors de lui, etc).
exemple Confirmmbox au-dessus de son ImageButton "source" (poubelle)
/**
* A custom DialogFragment that is positioned above given "source" component.
*
* @author Jonik, https://stackoverflow.com/a/20419231/56285
*/
public class ConfirmBox extends DialogFragment {
private View source;
public ConfirmBox() {
}
public ConfirmBox(View source) {
this.source = source;
}
public static ConfirmBox newInstance(View source) {
return new ConfirmBox(source);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_FRAME, R.style.Dialog);
}
@Override
public void onStart() {
super.onStart();
// Less dimmed background; see /q/dialogfragment-with-clear-background-not-dimmed-11668/"source" view
*/
private void setDialogPosition() {
if (source == null) {
return; // Leave the dialog in default position
}
// Find out location of source component on screen
// see https://stackoverflow.com/a/6798093/56285
int[] location = new int[2];
source.getLocationOnScreen(location);
int sourceX = location[0];
int sourceY = location[1];
Window window = getDialog().getWindow();
// set "origin" to top left corner
window.setGravity(Gravity.TOP|Gravity.LEFT);
WindowManager.LayoutParams params = window.getAttributes();
// Just an example; edit to suit your needs.
params.x = sourceX - dpToPx(110); // about half of confirm button size left of source view
params.y = sourceY - dpToPx(80); // above source view
window.setAttributes(params);
}
public int dpToPx(float valueInDp) {
DisplayMetrics metrics = getActivity().getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}
}
il est assez facile de généraliser l'utilisation ci-dessus en ajoutant des paramètres de constructeur ou des setters si nécessaire. (Mon dernier ConfirmBox
a un bouton stylé (à l'intérieur de certaines frontières etc) dont le texte et View.OnClickListener
peuvent être personnalisés en code.)
getDialog().getWindow()
ne fonctionnera pas pour un DialogFragment
car getWindow()
retournera nul si l'activité d'hébergement n'est pas visible, ce qui n'est pas le cas si vous écrivez une application basée sur des fragments. Vous obtiendrez un NullPointerException
en essayant getAttributes()
.
je recommande la réponse de Mobistry. Si vous avez déjà une classe DialogFragment, il n'est pas trop difficile de basculer. Il suffit de remplacer la méthode onCreateDialog par une méthode qui construit et renvoie un PopupWindow. Ensuite, vous devriez être en mesure pour réutiliser la vue que vous fournissez à AlertDialog.builder.setView()
, et appelez (PopupWindow object).showAtLocation()
.
j'utilise la classe PopupWindow à cet effet parce que vous pouvez spécifier l'emplacement et la taille de la vue.
vous devez modifier la méthode onResume () dans votre fragment de dialogue comme suit:
@Override
public void onResume() {
final Window dialogWindow = getDialog().getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.x = 100; // set your X position here
lp.y = 200; // set your Y position here
dialogWindow.setAttributes(lp);
super.onResume();
}