自定义FragmentDialog具有圆角而不是100%的屏幕宽度

van*_*dus 33 android custom-component android-dialogfragment

我正在创建一个自定义片段对话框,其圆角和布局不会填满屏幕宽度(我更喜欢它只是包装其内容).

这是我rounded_dialog.xml的drawable文件夹,由我的Custom调用,ThemeWithCorners作为对话框的背景.我还尝试将其设置为线性布局的背景,该布局创建其内容但没有任何作用.

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" 
>
<solid android:color="@android:color/white"/>
<corners android:radius="20dp"
/>
</shape>
Run Code Online (Sandbox Code Playgroud)

这就是我调用对话框的方式:

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();
Run Code Online (Sandbox Code Playgroud)

在对话框的onCreate方法中我设置了样式和主题:

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

这是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;
}
Run Code Online (Sandbox Code Playgroud)

我也尝试将此添加到onCreateDialog方法,因为SO上的其他答案建议但不起作用:

@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;
}
Run Code Online (Sandbox Code Playgroud)

总而言之,我想要圆角,而不是100%宽度的屏幕,它最好应该包裹它的内容.拜托,拜托,我需要一些帮助,我真的非常绝望,我已经好几天了!

Dav*_*uel 65

对话背景: 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>
Run Code Online (Sandbox Code Playgroud)

对话框布局: 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>
Run Code Online (Sandbox Code Playgroud)

对话片段: 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;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

圆角对话框

更新:如果未设置标记Window.FEATURE_NO_TITLE,则在Android≤4.4的设备中,对话框顶部会出现蓝线.

  • 我相信这是更好的解决方案.感谢分享! (6认同)
  • 此解决方案也适用于 `ConstraintLayout` 而不是 `LinearLayout`。 (2认同)

van*_*dus 43

好吧,我刚刚找到了解决方案,但我对此并不满意.

我为对话框设置了背景(rounded_dialog.xml),如下所示:

<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>
Run Code Online (Sandbox Code Playgroud)

然后我通过下面的'onCreateView'方法将其设置为我的对话框.在这段代码中,圆角并不是必需的,因为背景是透明的,但填充很重要,因为对话框实际上仍然和屏幕一样宽,但是填充使它看起来不像.

getDialog().getWindow().setBackgroundDrawableResource(R.drawable.rounded_dialog);
Run Code Online (Sandbox Code Playgroud)

最后,我将对话框组件的背景设置为另一个自定义drawable,使角落变圆.我有一个LinearLayout,其顶部是RelativeLayout,底部是TextView,因此我将@null设置为父LinearLayout,并将两个不同的自定义drawable设置为两个部分,其中一个部分具有圆形bottomCorners,另一个部分具有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>
Run Code Online (Sandbox Code Playgroud)

我相信有一个更合适的解决方案,因为这在视觉上是正确的,而不是真正的功能,但对于这种情况足够正确.


Alo*_*der 5

使用 Kotlin 和 View Binding 更新了 2021 年的答案 -

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
    }

}
Run Code Online (Sandbox Code Playgroud)