Aangepaste fragmentdialog met ronde hoeken en niet 100% schermbreedte

Ik maak een aangepast fragmentdialoog met ronde hoeken en met lay-out die de schermbreedte niet zou vullen (ik zou de voorkeur geven als het zijn inhoud ingepakt).

Dit is mijn rounded_dialog.xmlin de opleiding map, die wordt opgeroepen door mijn aangepaste ThemeWithCornersals achtergrond voor het dialoogvenster. Ik heb ook geprobeerd het als achtergrond in te stellen voor de lineaire lay-out die zijn inhoud creëert, maar niets werkt.

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

En dit is hoe ik het dialoogvenster bel:

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

In oncreate-methode van het dialoogvenster stel ik de stijl en thema in:

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

Dit is de oncreateview-methode:

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

Ik heb ook geprobeerd dit toe te voegen aan oncreatedialog-methode als andere antwoorden op zo gesuggereerd, maar werkte ook:

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

Dus om het op te vatten, wil ik ronde hoeken, niet 100% breedte van het scherm, het moet bij voorkeur zijn inhoud inpakken. Alsjeblieft, alsjeblieft, ik heb hulp nodig, ik ben er echt wanhopig over, ik probeer het voor dagen!


Antwoord 1, Autoriteit 100%

Dialoog Achtergrond: 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>

Dialog Layout: 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>

Dialoogvenster Fragment: 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;
    }
    ...
}

Update: Als u niet instellen van de vlag Window.FEATURE_NO_TITLE, een blauwe lijn verschijnt op de top van de dialoog in apparaten met Android ≤ 4,4.


Antwoord 2, Autoriteit 44%

Nou, ik heb net een oplossing, ik ben niet echt blij met het wel.

Ik stel de achtergrond (rounded_dialog.xml) voor het dialoogvenster als volgt:

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

Toen zette ik dit aan mijn dialoog in zijn’onCreateView’ methode op deze manier hieronder. De afgeronde hoeken zijn niet echt nodig in dit stuk van code als de achtergrond is transparant, maar de opvulling is belangrijk, omdat de dialoog is nog steeds in feite zo breed als het scherm, maar de opvulling maakt het eruit alsof het niet.

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

En op het einde I set achtergrond van de dialog’s componenten aan andere aangepaste betekenbare waarbij de hoeken round maakt. Ik heb een LinearLayout met RelativeLayout bovenaan TextView onderaan, dus stel @null de bovenliggende LinearLayout en set twee verschillende aangepaste drawables om de twee delen, waarvan een afgeronde bottomCorners en de andere 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>

Ik geloof dat er een goede oplossing voor dit als dit juist is alleen visueel, niet echt functioneel, maar genoeg juist voor dit geval.


Antwoord 3, Autoriteit 5%

Bijgewerkt 2022 antwoord met Kotlin en bekijken Binding –

class InternetLostDialog : DialogFragment() {
    private lateinit var binding: DialogInternetLostBinding
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        binding = DialogInternetLostBinding.inflate(LayoutInflater.from(context))
        val builder = AlertDialog.Builder(requireActivity())
        isCancelable = false
        builder.setView(binding.root)
        binding.root.setOnClickListener {
            requireActivity().finish()
        }
        val dialog = builder.create()
        dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        return dialog
    }
}

Antwoord 4, Autoriteit 2%

Een andere manier:

Gebruik setStyle()in de methode onCreate()om een stijl toe te passenop uw DialogFragment.
Vervolgens, je kunt android:backgroundhetzelfde gebruiken als altijd in de rootweergavevan het your_layout.xml-bestand.


Stappen:

  1. style.xmlbestand (in resmap):
<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. Maak your_layout.xmlbestand in de layout map:
<?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. Maak bg_corner_dialog.xmlbestand in de tekenmap:
<?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. Pas ten slotte styleen layouttoe op uw 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;
    }
}

Ik hoop dat dit je helpt.
Beste wensen


Antwoord 5

Een bijgewerkte oplossing die voor mij werkt met Kotlin.

Ik heb de achtergrond (rounded_dialog.xml) voor het dialoogvenster als volgt ingesteld:

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

bereken vervolgens programmatisch de schermbreedte en trek vervolgens de margewaarde ervan af met behulp van dit codefragment.

val displayMetrics = DisplayMetrics()
        requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
        val width = displayMetrics.widthPixels

vervolgens binnen onStart callback heb ik die breedte minus marge toegepast.
hier is de volledige code.

@AndroidEntryPoint
class CancelDialogFragment : DialogFragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (dialog != null && dialog?.window != null) {
            dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
            dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE);
        }
        return inflater.inflate(R.layout.fragment_cancel_dialog, container, false)
    }
    override fun onStart() {
        super.onStart()
        val displayMetrics = DisplayMetrics()
        requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
        val width = displayMetrics.widthPixels
        val height = displayMetrics.heightPixels
        dialog?.window?.setLayout(width-64, ViewGroup.LayoutParams.WRAP_CONTENT)
    }
}

XML-layout fragment_cancel_dialog

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingVertical="32dp"
    android:padding="8dp"
    android:layout_marginHorizontal="8dp"
    android:background="@drawable/rounded_dialog"
    tools:context=".ui.orders.CancelDialogFragment">
    <TextView
        android:id="@+id/textView9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Reason of cancellation"
        android:textSize="16sp"
        app:layout_constraintStart_toStartOf="@+id/firstNameTIL"
        app:layout_constraintTop_toTopOf="parent" />
    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/firstNameTIL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="24dp"
        android:layout_marginTop="16dp"
        app:hintAnimationEnabled="false"
        app:hintEnabled="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView9">
        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/firstNameET"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/edit_text_bg"
            android:drawablePadding="12dp"
            android:inputType="textPersonName"
            android:paddingHorizontal="16dp"
            android:paddingVertical="16dp"
            android:textAlignment="viewStart"
            android:textColor="@color/textColor"
            android:textColorHint="@color/black" />
    </com.google.android.material.textfield.TextInputLayout>
    <Button
        android:id="@+id/signUpButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="32dp"
        android:background="@drawable/button_bg"
        android:paddingHorizontal="56dp"
        android:text="@string/confirmStr"
        android:textAllCaps="false"
        android:inputType="text"
        android:textColor="@color/black"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/firstNameTIL" />
</androidx.constraintlayout.widget.ConstraintLayout>


Antwoord 6

Ik denk dat het veel gemakkelijker is om afgeronde hoeken te maken als je cardview als root van je lay-out maakt en onderstaande code toevoegt in onCreateView():
alertDialog.getWindow().setBackgroundDrawableResource(android.R.color.transpare‌​nt)


Antwoord 7

Voor iedereen die de AlertDialogBuilder wil gebruiken en de achtergrond transparant wil maken en het Drawable in XML-bestand wil instellen.

<style name="DialogStyle" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
<item name="android:background">@drawable/dialog_background</item>
<item name="android:windowBackground">@android:color/transparent</item>

Stel dit thema in op Builder zoals hieronder

private val builder: AlertDialog.Builder = AlertDialog.Builder(context,R.style.DialogStyle)
    .setView(dialogView)

waar is R.drawable.dialog_background

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape android:shape="rectangle" android:padding="10dp">
        <solid
            android:color="@color/dialog_bg_color"/>
        <corners
            android:radius="30dp" />
    </shape>
</item>

Antwoord 8

Er is een snelle oplossing voor DialogFragment. Bijvoorbeeld in de methode onCreateDialog() stijl toevoegen:

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    View view = LayoutInflater.from(getActivity()).inflate(R.layout.custom_dialog_lauout, null);
    return new AlertDialog.Builder(getActivity(), R.style.custom_alert_dialog)
            .setView(view)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int i) {
                    // do something
                }
            })
            .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            })
            .create();
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.custom_alert_dialog);

In de map stijlencustom_alert_dialog

<style name="custom_alert_dialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:windowBackground">@drawable/corner_background</item>
</style>

In tekenbare map corner_background.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:radius="8dp" />

Het is getest op API >= 21

Other episodes