我在Android应用程序中创建了一个自定义对话框首选项,但是我不知道如何获取显示的对话框以覆盖整个显示宽度。

image of dialog with too much space on left and right side

我发现了许多建议的解决方案,以在全屏模式下获得普通对话框


Android get full width for custom Dialog
https://gist.github.com/koocbor/88db64192638bff09aa4
http://blog.jimbaca.com/force-dialog-to-take-up-full-screen-width/


但是通过getWindow设置属性不起作用:

@Override
public Dialog getDialog() {

    Dialog dialog = super.getDialog();
    dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    // or
    // dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    return dialog;
}


并且将全屏主题应用于我的对话框的根元素也没有完成这项工作:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    [...]
    android:theme="@style/FullscreenTheme">


此外,我无法访问对话框的onCreate方法(至少我不知道如何),无法在其中设置样式。

有谁遇到过同样的问题,并为这个非常具体的问题找到了解决方案?

我的布局:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:orientation="vertical"
    android:padding="0dp"
    android:paddingTop="@dimen/preferences_dialog_def_padding"
    android:paddingBottom="@dimen/preferences_dialog_def_padding">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <View
            android:layout_width="match_parent"
            android:layout_height="2dp"
            android:layout_marginTop="-2dp"
            android:background="@color/expandable_preference_divider"/>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/preferences_expandable_margin_top_bottom"
            android:layout_marginTop="@dimen/preferences_expandable_margin_top_bottom">

            <RelativeLayout
                android:id="@+id/icon_wrapper_choose"
                android:layout_width="@dimen/preferences_expandable_icon_wrapper_size"
                android:layout_height="@dimen/preferences_expandable_icon_wrapper_size"
                android:layout_marginBottom="0dp"
                android:layout_marginEnd="@dimen/preference_expandable_icon_margin"
                android:layout_marginStart="@dimen/preference_expandable_icon_margin"
                android:layout_marginTop="0dp"
                android:gravity="center">

                <ImageView
                    android:layout_width="@dimen/preferences_expandable_icon_size"
                    android:layout_height="@dimen/preferences_expandable_icon_size"
                    android:layout_centerHorizontal="true"
                    android:layout_centerVertical="true"
                    android:cropToPadding="true"
                    android:scaleType="centerCrop"
                    android:src="@drawable/ic_settings_white_36dp"/>

            </RelativeLayout>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_toEndOf="@+id/icon_wrapper_choose"
                android:paddingBottom="@dimen/preferences_expandable_text_padding_top_bottom"
                android:paddingTop="@dimen/preferences_expandable_text_padding_top_bottom"
                android:text="@string/pref_wheel_circumference_choose"
                android:textColor="@color/colorAccent"
                android:textSize="@dimen/text_size_medium"
                android:textStyle="bold"/>
        </RelativeLayout>

        <TextView
            android:layout_width="match_parent"
            android:layout_marginEnd="@dimen/preference_expandable_icon_margin"
            android:layout_marginStart="@dimen/preference_expandable_icon_margin"
            android:layout_height="wrap_content"
            android:text="@string/etrto_hint"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:minHeight="?android:attr/listPreferredItemHeight"
            android:orientation="horizontal"
            android:paddingBottom="20dp"
            android:paddingEnd="?android:attr/scrollbarSize"
            android:layout_marginStart="@dimen/preference_expandable_icon_margin"
            android:weightSum="3"
            >

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/etrto"/>

            <Spinner
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingBottom="20dp"
            android:paddingEnd="?android:attr/scrollbarSize"
            android:layout_marginStart="@dimen/preference_expandable_icon_margin"
            android:weightSum="3"
            >

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/manufacturer"/>

            <Spinner
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"/>

        </LinearLayout>

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_marginTop="-2dp"
        android:background="@color/expandable_preference_divider"/>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/preference_category_wrapper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true"
        android:orientation="vertical"
        android:padding="5dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/preferences_expandable_margin_top_bottom"
            android:layout_marginTop="@dimen/preferences_expandable_margin_top_bottom">

            <RelativeLayout
                android:id="@+id/icon_wrapper_manual"
                android:layout_width="@dimen/preferences_expandable_icon_wrapper_size"
                android:layout_height="@dimen/preferences_expandable_icon_wrapper_size"
                android:layout_marginBottom="0dp"
                android:layout_marginEnd="@dimen/preference_expandable_icon_margin"
                android:layout_marginStart="@dimen/preference_expandable_icon_margin"
                android:layout_marginTop="0dp"
                android:gravity="center">

                <ImageView
                    android:id="@+android:id/icon"
                    android:layout_width="@dimen/preferences_expandable_icon_size"
                    android:layout_height="@dimen/preferences_expandable_icon_size"
                    android:layout_centerHorizontal="true"
                    android:layout_centerVertical="true"
                    android:cropToPadding="true"
                    android:scaleType="centerCrop"
                    android:src="@drawable/ic_edit_white_36dp"/>

            </RelativeLayout>

            <TextView
                android:id="@+android:id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toEndOf="@+id/icon_wrapper_manual"
                android:paddingBottom="@dimen/preferences_expandable_text_padding_top_bottom"
                android:paddingTop="@dimen/preferences_expandable_text_padding_top_bottom"
                android:text="@string/pref_wheel_circumference_manually"
                android:textColor="@color/colorAccent"
                android:textSize="@dimen/text_size_medium"
                android:textStyle="bold"/>
        </RelativeLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:minHeight="?android:attr/listPreferredItemHeight"
            android:orientation="horizontal"
            android:paddingBottom="20dp"
            android:paddingEnd="?android:attr/scrollbarSize"
            android:layout_marginStart="@dimen/preference_expandable_icon_margin"
            android:weightSum="2.5"
            >

            <EditText
                android:id="@+id/pref_dialog_wheelcircumference_et"
                android:layout_width="0dp"
                android:layout_weight="2"
                android:layout_height="wrap_content"
                android:textAlignment="textEnd"
                android:textColor="@color/colorFont"
                android:textSize="@dimen/text_size_small"
                android:inputType="number"/>

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.5"
                android:textAlignment="center"
                android:text="@string/wheel_circumference_unit"/>

        </LinearLayout>

    </LinearLayout>
</LinearLayout>


我的自定义偏好类别

public class WheelCircumferencePreference extends android.preference.DialogPreference {

private static String TAG = "CustomSwitchPreference";
private int mWheelCircumference;
public static int WHEEL_CIRCUMFERENCE_DEFAULT = 2125;

private int mDialogLayoutResId = R.layout.pref_dialog_wheelcircumference;

public WheelCircumferencePreference(Context context) {
    this(context, null);
}

public WheelCircumferencePreference(Context context, AttributeSet attrs) {
    this(context, attrs, R.attr.dialogPreferenceStyle);
}

public WheelCircumferencePreference(Context context, AttributeSet attrs,
                                    int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setLayoutResource(R.layout.custom_preference);
    setDialogLayoutResource(mDialogLayoutResId);
    setPositiveButtonText(getContext().getString(R.string.dialog_save));
    setNegativeButtonText(getContext().getString(R.string.dialog_cancel));
}

@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
    // Default value from attribute. Fallback value is set to WHEEL_CIRCUMFERENCE_DEFAULT.
    return a.getInteger(index, WHEEL_CIRCUMFERENCE_DEFAULT);
}

@Override
protected void onSetInitialValue(boolean restorePersistedValue,
                                 Object defaultValue) {
    would load value from shared preferences
    if (restorePersistedValue) {
        mWheelCircumference = getPersistedInt(WHEEL_CIRCUMFERENCE_DEFAULT);
    } else {
        mWheelCircumference = (Integer) defaultValue;
        persistInt(mWheelCircumference);
    }
}

private EditText mWheelCircumferenceEt;


@Override
protected void onBindDialogView(View view) {

    mWheelCircumferenceEt = view.findViewById(R.id.pref_dialog_wheelcircumference_et);

    if (mWheelCircumferenceEt == null) {
        throw new IllegalStateException("preference dialog view must contain" +
                " a EditText with id 'pref_dialog_wheelcircumference_et'");
    }
    mWheelCircumferenceEt.setText(Integer.toString(mWheelCircumference));


    super.onBindDialogView(view);
}



@Override
public Dialog getDialog() {

    //Dialog dialog = super.getDialog();

   // WindowManager.LayoutParams p = getDialog().getWindow().getAttributes();
    //p.height = LinearLayout.LayoutParams.WRAP_CONTENT;
    //dialog.getWindow().setAttributes(p);

    return dialog;
}

@Override
protected void onDialogClosed(boolean positiveResult) {
    if (positiveResult) {
        String circumferenceText = mWheelCircumferenceEt.getText().toString();

        try {
            mWheelCircumference = Integer.parseInt(circumferenceText);
        } catch (Exception e) {
            NLog.e(TAG, "onDialogClosed - ", e);
            mWheelCircumference = WheelCircumferencePreference.WHEEL_CIRCUMFERENCE_DEFAULT;
        }
        persistInt(mWheelCircumference);
    }
}


编辑:

实际上,我只希望对话框跨越屏幕的整个宽度,而不是高度。如果我要使用一个附加的PreferenceFragment(因为DialogPreference已经嵌入在PreferenceFragment中),那么“ Dialog”(又名Fragment)将采用完整的宽度和高度(我想)。

我已经实现了没有DialogPrefrence的解决方案,该解决方案虽然有效,但并不完美


仅使用普通的EditTextPreference
在我的SettingsFragment代码中向此首选项添加onPreferenceClickListener


ClickListener显示一个简单的对话框



例:

        Preference preference = findPreference(EXAMPLE_PREFRENCE);

        if (preference != null) {

            preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
                @Override
                public boolean onPreferenceClick(Preference preference) {
//                    showDialog();
                }
            });


但是由于我有很多首选项,它们会显示对话框,所以对话框创建和显示的代码会加载SettingsFragment并使它几乎不可读。因此,我认为将显示对话框和处理首选项值的责任放在Preference和XML布局上将是一个不错的解决方案。

不幸的是,我陷入了上面提到的“全角问题”。

注意:修复了我测试不同版本时的getDialog代码(也与xml主题集结合使用)

最佳答案

最后,我确实找到了解决此问题的方法:

在showDialog方法中获取首选项的AlertDialog

@Override
protected void showDialog(Bundle state) {
        super.showDialog(state);
        CustomDialogPreference.makeDialogFullScreen((AlertDialog) getDialog());
}


使它跨越整个宽度:

public static void makeDialogFullScreen(AlertDialog d) {
    NLog.d(TAG, "makeDialogFullScreen enter ");
    if (d != null) {
        ViewGroup.LayoutParams params = d.getWindow().getAttributes();
        if (params != null) {
            params.width = WindowManager.LayoutParams.MATCH_PARENT;
            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
            d.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
        }
    }
}

08-05 04:43
查看更多