web-dev-qa-db-fra.com

FragmentDialog personnalisé avec des coins arrondis et pas une largeur d'écran de 100%

Je crée une boîte de dialogue de fragment personnalisé avec des coins arrondis et avec une disposition qui ne remplirait pas la largeur de l'écran (je préférerais qu'elle enveloppe simplement son contenu).

c'est mon rounded_dialog.xml dans le dossier dessinable, qui est appelé par mon personnalisé ThemeWithCorners comme arrière-plan de la boîte de dialogue. J'ai également essayé de le définir comme arrière-plan de la mise en page linéaire qui crée son contenu, mais rien ne fonctionne.

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle" 
>
<solid Android:color="@Android:color/white"/>
<corners Android:radius="20dp"
/>
</shape>

et voici comment j'appelle la boîte de dialogue:

final String FTAG = "TAG_FRAGMENT_DIALOG_CALENDAR";
    dialog = (CalendarDialog) fm.findFragmentByTag(FTAG);
    ft = fm.beginTransaction();
    if (dialog != null)
    {
        ft.remove(dialog);
    }
    dialog = CalendarDialog.newInstance(this);      
    dialog.setCancelable(true);

    ft.add(dialog, FTAG);
    ft.show(dialog);
    ft.commit();

Dans la méthode onCreate de la boîte de dialogue, j'ai défini le style et le thème:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NO_TITLE, R.style.ThemeWithCorners);      
}

Voici la méthode onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
getDialog().setCanceledOnTouchOutside(true);
v = (MyCalendar)inflater.inflate(R.layout.calendar_dialog, container, true)
    return v;
}

J'ai également essayé d'ajouter ceci à la méthode onCreateDialog comme d'autres réponses sur SO suggéré mais n'a pas fonctionné non plus:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    Dialog d =  super.onCreateDialog(savedInstanceState);
    LayoutParams lp=d.getWindow().getAttributes();
    d.getWindow().setBackgroundDrawable(new ColorDrawable(0));
    lp.width=-2;lp.height=-2;lp.gravity=Gravity.CENTER;
    lp.dimAmount=0;            
    lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS | LayoutParams.FLAG_NOT_TOUCH_MODAL;

    return d;
}

Donc, pour résumer, je veux des coins arrondis, pas 100% de largeur de l'écran, il devrait de préférence envelopper son contenu. S'il vous plaît, s'il vous plaît, j'ai besoin d'aide, je suis vraiment désespéré à ce sujet, je l'ai essayé pendant des jours!

39
vandus

Eh bien, je viens de trouver une solution, je n'en suis pas vraiment satisfaite.

J'ai défini l'arrière-plan (round_dialog.xml) pour la boîte de dialogue comme ceci:

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle">
<solid Android:color="@Android:color/transparent"/>
<corners Android:radius="10dp" />
<padding Android:left="10dp" Android:right="10dp"/>
</shape>

Ensuite, je l'ai défini dans ma boîte de dialogue dans sa méthode "onCreateView" de cette façon ci-dessous. Les coins arrondis ne sont pas vraiment nécessaires dans ce morceau de code car l'arrière-plan est transparent, mais le remplissage est important, car la boîte de dialogue est toujours aussi large que l'écran, mais le remplissage donne l'impression qu'il ne l'est pas.

getDialog().getWindow().setBackgroundDrawableResource(R.drawable.rounded_dialog);

Et à la fin, j'ai défini l'arrière-plan des composants de la boîte de dialogue sur un autre dessin personnalisé qui rend les coins arrondis. J'ai un LinearLayout avec RelativeLayout en haut et TextView en bas, j'ai donc défini @null sur le LinearLayout parent et défini deux dessinables personnalisés différents sur les deux parties, dont l'une a arrondi bottomCorners et l'autre topCorners.

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:orientation="vertical" 
Android:background="@drawable/title_round"  
>

<RelativeLayout
    Android:id="@+id/title"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"        
    Android:orientation="horizontal" 
    Android:background="@drawable/blue_title_round_top"
    Android:paddingTop="4dp"
    Android:paddingBottom="4dp"
    >
<TextView 
    Android:id="@+id/calendarHint"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@drawable/rounded_bottom"
    Android:layout_gravity="center"
    Android:gravity="center"
        />
</LinearLayout>

Je crois qu'il y a une solution plus appropriée à cela car c'est correct visuellement, pas vraiment sur le plan fonctionnel, mais assez correct pour ce cas.

44
vandus

Arrière-plan de la boîte de dialogue: dialog_rounded_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="rectangle">
    <solid Android:color="@Android:color/white" />
    <corners Android:radius="12dp" />
</shape>

Disposition de la boîte de dialogue: dialog_rounded.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:background="@drawable/dialog_rounded_bg"
    Android:minWidth="260dp"
    Android:orientation="vertical"
    Android:padding="24dp">
    ...
</LinearLayout>

Fragment de dialogue: RoundedDialog.Java

public class RoundedDialog extends DialogFragment {
    ...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dialog_rounded, container, false);
        // Set transparent background and no title
        if (getDialog() != null && getDialog().getWindow() != null) {
            getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        }
        return view;
    }
    ...
}

Rounded dialog

Mise à jour: Si vous ne définissez pas le drapeau Window.FEATURE_NO_TITLE, a la ligne bleue apparaît en haut de la boîte de dialogue sur les appareils avec Android ≤ 4.4.

76
David Miguel

Autrement:
Utilisez setStyle() dans la méthode onCreate() pour appliquer un style à votre DialogFragment.
Ensuite, vous pouvez utiliser Android:background comme toujours dans la vue racine de your_layout.xml fichier.


Pas:

  1. style.xml fichier (dans le dossier res):
<style name="DialogTheme_transparent" parent="Theme.AppCompat.Dialog">
    <item name="Android:windowBackground">@Android:color/transparent</item>
    <!--You can set other style items also, such as animations and etc-->
</style>
  1. Créer your_layout.xml fichier dans le dossier de mise en page:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:padding="8dp"
    Android:background="@drawable/bg_corner_dialog">
    ...
</LinearLayout>
  1. Créer bg_corner_dialog.xml fichier dans le dossier dessinable:
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="rectangle"
    Android:dither="true">
    <solid Android:color="#ffffff"/>
    <corners Android:radius="16dp"/>
</shape>
  1. Enfin, appliquez style et layout à votre DialogFragment:
public class CustomDialogFragment extends DialogFragment {
    ...

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE, R.style.DialogTheme_transparent);
        ...
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.your_layout, container, false);
        ButterKnife.bind(this, v);
        //init UI Elements...
        return v;
    }

}

J'espère que ceci vous aide.
Meilleurs vœux

0
Ghasem Sadeghi