Quelqu'un sait-il comment définir des marges dans une boîte de dialogue personnalisée? Je demande parce que j'ai une boîte de dialogue personnalisée, mais lorsqu'elle est affichée, elle s'étend pour remplir le parent, même si j'ai défini explicitement WRAP_CONTENT sur les paramètres de présentation.
Fondamentalement, la boîte de dialogue contient une liste contenant les éléments à faire défiler. Lorsque les éléments sont 1, par exemple, elle ne s’étire pas, mais lorsque plusieurs éléments sont ajoutés, la boîte de dialogue occupe tout l’écran.
Aucune suggestion? J'ai essayé toutes les combinaisons possibles de solutions possibles sans obtenir de résultats satisfaisants
EDIT: Ajout de la disposition du dialogue
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_margin="50dip"
Android:orientation="vertical"
Android:layout_gravity="top|center">
<FrameLayout Android:layout_width="fill_parent" Android:layout_margin="5dip" Android:layout_height="wrap_content">
<TextView Android:layout_width="wrap_content" Android:layout_height="wrap_content"
Android:layout_gravity="center"
Android:textSize="20sp" Android:textColor="@color/black"/>
<Button Android:layout_height="32dip" Android:layout_width="32dip"
Android:id="@+id/guide_dialog_cross_button"
Android:background="@drawable/button_cross_white"/>
</FrameLayout>
<ListView Android:layout_width="fill_parent" Android:layout_height="wrap_content"
Android:fadingEdge="none"
Android:layout_margin="5dip"/>
<ImageButton Android:layout_width="wrap_content" Android:layout_height="wrap_content"
Android:layout_margin="5dip" />
</LinearLayout>
Les marges ne fonctionnent pas pour les boîtes de dialogue, j'imagine que la vue de la fenêtre de niveau supérieur n'est pas un type de présentation qui prend en charge les marges. J'ai vu des publications dire que les marges fonctionneraient si elles étaient définies comme étant le style de la boîte de dialogue (plutôt que dans l'élément de vue de niveau supérieur), mais cela ne semble pas fonctionner non plus.
Ce que vous devez faire pour contourner le problème consiste à utiliser une variable inset
à dessiner pour l'arrière-plan de la boîte de dialogue et d'ajuster tout remplissage pour tenir compte de l'encart supplémentaire de l'arrière-plan. Dans l'exemple ci-dessous, je vais simplement définir les marges gauche et droite.
Boîte de dialogue dessinable:
<?xml version="1.0" encoding="utf-8"?>
<!-- drawable is a reference to your 'real' dialog background -->
<!-- insetRight and insetLeft add the margins -->
<inset
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:drawable="@drawable/dialog_background"
Android:insetRight="10dp"
Android:insetLeft="10dp">
</inset>
Vue principale du dialogue:
<?xml version="1.0" encoding="utf-8"?>
<!-- paddingTop / paddingBottom padding for the dialog -->
<!-- paddingLeft / paddingRight padding must add the additional inset space to be consistent -->
<!-- background references the inset background drawable -->
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:paddingTop="5dp"
Android:paddingBottom="5dp"
Android:paddingLeft="15dp"
Android:paddingRight="15dp"
Android:background="@drawable/dialog_background_inset">
<!-- ...the rest of the layout... -->
Vous devrez peut-être également définir la couleur d’arrière-plan du dialogue lui-même sur transparent. Ajouter une ressource de couleur comme ceci:
<color name="transparent">#00000000</color>
Et définissez la couleur d'arrière-plan de la fenêtre sur la boîte de dialogue (remarque: vous ne pouvez pas attribuer directement la couleur, Eclipse se plaindra).
<style name="Dialog" parent="Android:style/Theme.Dialog">
<item name="Android:windowBackground">@color/transparent</item>
<item name="Android:windowNoTitle">true</item>
<item name="Android:windowIsFloating">true</item>
</style>
Ce style doit être transmis au constructeur de votre dialogue sous forme d'argument theme
, comme dans new Dialog(context, R.style.Dialog);
.
La marge ne semble pas fonctionner sur la disposition personnalisée de la boîte de dialogue, mais le remplissage fonctionne. Essayez de définir le remplissage sur la disposition linéaire de niveau supérieur.
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingLeft="4dp"
Android:paddingRight="4dp" >
J'ai eu le même problème et je l'ai résolu en définissant le fond de la fenêtre sur InsetDrawable:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
...
...
AlertDialog dialog = builder.create();
ColorDrawable back = new ColorDrawable(Color.TRANSPARENT);
InsetDrawable inset = new InsetDrawable(back, 20);
dialog.getWindow().setBackgroundDrawable(inset);
dialog.show();
Dans ce cas, la boîte de dialogue apparaît avec une marge de 20 pour toutes les arêtes.
Une solution de contournement peut être faite comme ceci:
dialog.getWindow().getAttributes().height =
(int) (getDeviceMetrics(context).heightPixels*0.8);
` getDeviceMetrics Method:
public static DisplayMetrics getDeviceMetrics(Context context) {
DisplayMetrics metrics = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
display.getMetrics(metrics);
return metrics;
}
C'est un moyen simple et programmatique de définir la position et la taille de mon dialogue avec les marges.
J'ai testé mon approche pour une DialogFragment
en l'appliquant dans la méthode onCreateDialog
:
public Dialog onCreateDialog( Bundle savedInstanceState )
{
// create dialog in an arbitrary way
Dialog dialog = super.onCreateDialog( savedInstanceState );
DialogUtils.setMargins( dialog, 0, 150, 50, 75 );
return dialog;
}
C'est la méthode qui applique les marges à la boîte de dialogue:
public static Dialog setMargins( Dialog dialog, int marginLeft, int marginTop, int marginRight, int marginBottom )
{
Window window = dialog.getWindow();
if ( window == null )
{
// dialog window is not available, cannot apply margins
return dialog;
}
Context context = dialog.getContext();
// set dialog to fullscreen
RelativeLayout root = new RelativeLayout( context );
root.setLayoutParams( new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) );
dialog.requestWindowFeature( Window.FEATURE_NO_TITLE );
dialog.setContentView( root );
// set background to get rid of additional margins
window.setBackgroundDrawable( new ColorDrawable( Color.WHITE ) );
// apply left and top margin directly
window.setGravity( Gravity.LEFT | Gravity.TOP );
LayoutParams attributes = window.getAttributes();
attributes.x = marginLeft;
attributes.y = marginTop;
window.setAttributes( attributes );
// set right and bottom margin implicitly by calculating width and height of dialog
Point displaySize = getDisplayDimensions( context );
int width = displaySize.x - marginLeft - marginRight;
int height = displaySize.y - marginTop - marginBottom;
window.setLayout( width, height );
return dialog;
}
Voici les méthodes d'assistance que j'ai utilisées:
@NonNull
public static Point getDisplayDimensions( Context context )
{
WindowManager wm = ( WindowManager ) context.getSystemService( Context.WINDOW_SERVICE );
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics( metrics );
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
// find out if status bar has already been subtracted from screenHeight
display.getRealMetrics( metrics );
int physicalHeight = metrics.heightPixels;
int statusBarHeight = getStatusBarHeight( context );
int navigationBarHeight = getNavigationBarHeight( context );
int heightDelta = physicalHeight - screenHeight;
if ( heightDelta == 0 || heightDelta == navigationBarHeight )
{
screenHeight -= statusBarHeight;
}
return new Point( screenWidth, screenHeight );
}
public static int getStatusBarHeight( Context context )
{
Resources resources = context.getResources();
int resourceId = resources.getIdentifier( "status_bar_height", "dimen", "Android" );
return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}
public static int getNavigationBarHeight( Context context )
{
Resources resources = context.getResources();
int resourceId = resources.getIdentifier( "navigation_bar_height", "dimen", "Android" );
return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}
Les méthodes auxiliaires sont expliquées dans une autre de mes SO réponses .
This Gist contient une version étendue qui prend également en charge le mode immersion.
1) modifiez votre hauteur de disposition parent principale match_content
comme ci-dessous:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="match_content"
Android:layout_margin="50dip"
Android:orientation="vertical"
Android:layout_gravity="top|center">
2) maintenant ajouter du style à votre styles.xml
<style name="dialogTheme" parent="Base.Theme.AppCompat.Light.Dialog.Alert"/>
3) ajoutez maintenant le code ci-dessous pour afficher la boîte de dialogue:
Dialog dialog = new Dialog(DayActivity.this, R.style.dialogTheme);
dialog.setContentView(R.layout.dialog_custom_layout);
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.show();
Une solution simple qui a fonctionné pour moi consistait à envelopper toute ma vue dans une autre, et à définir la marge qui correspond maintenant à la vue intérieure.
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content">
<LinearLayout
Android:layout_margin="22dp"
Android:orientation="vertical"
Android:layout_width="220dp"
Android:layout_height="wrap_content">
... Buttons, TextViews, etc
</LinearLayout>
</LinearLayout>
Obs: cela fonctionnait quand je voulais des marges dans mon AlertDialog. Pas en ce qui concerne l'écran.