全屏宽度的DialogPreference

时间:2018-03-21 15:40:20

标签: android

我在Android应用程序中创建了一个自定义对话框首选项,但我无法弄清楚如何让显示的对话框跨越整个显示宽度。

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

我发现许多建议的解决方案可以在全屏模式下获得正常的Dialog

但是通过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中)&#34;对话框&#34; (aka Fragment)将采用完整的宽度和高度(我猜)。

我已经实现了一个没有DialogPrefrence的解决方案,它可以工作,但不是很优雅

  • 仅使用普通的EditTextPreference
  • 在我的SettingsFragment Code中将onPreferenceClickListener添加到此首选项
    • ClickListener显示简单的Dialog

示例:

        Preference preference = findPreference(EXAMPLE_PREFRENCE);    

        if (preference != null) {

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

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

不幸的是我遇到了&#34;全宽问题&#34;如上所述。

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

3 个答案:

答案 0 :(得分:1)

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

在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);
        }
    }
}

答案 1 :(得分:0)

在对话框的onResume中尝试此操作。

   // Store access variables for window and blank point
    Window window = getDialog().getWindow();
    Point size = new Point();
    // Store dimensions of the screen in `size`
    Display display = window.getWindowManager().getDefaultDisplay();
    display.getSize(size);
    // Set the width of the dialog proportional to 75% of the screen width and height
    window.setLayout((int) (size.x * 0.75), (int) (size.y * 0.75));
    window.setGravity(Gravity.CENTER);
    // Call super onResume after sizing

相应调整为100%。它适用于dialogFragment。虽然没有为你的情况尝试过。

答案 2 :(得分:0)

等等,你不是在寻找沼泽标准'Pref设置用户选项出现在对话框中'是你吗?这几乎肯定已经在AndroidStudio的add activity...> Settings Activity锅炉板中完成,检查出来,或者查找样本设置应用程序

无论如何,我确实在我的应用程序中有一个全屏对话框,虽然它故意没有填满整个屏幕,我实际上现在使用的是带有一些片段的活动。

就我个人而言,我认为这就是你的问题,我记得当我第一次需要这样的对话时遇到这个问题。您应该只使用活动并进行导航(如果您想要全屏“弹出”类型的东西,您可以使用导航模式,使home / up按钮为'X'而不是'&lt;');

或者其他任何事情,您不需要明确地显示对话框,如果您这样做,则扩展活动或对话框并获得您想要的内容。

这是我的活动内容,以防任何用途

我的主题:

  <style name="AppTheme.FullScreenDialog"
                  parent="@style/Theme.AppCompat.Light.Dialog">
    <item name="windowActionBar">true</item>
    <item name="windowNoTitle">true</item>
</style>

我的onCreate要点:

 @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    ...

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    ...
    super.onCreate(savedInstanceState);
    setContentView(getConcreteContentView());
    ButterKnife.bind(this);
    setUpUIComponents();
    ...
}

我的总体布局要点:

<CoordinatorLayout>
<AppBarLayout>
    <android.support.v7.widget.Toolbar/>
</android.support.design.widget.AppBarLayout>

<RelativeLayout
    android:id="@+id/container_main"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:paddingTop="6dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <RelativeLayout
        android:id="@+id/container_recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_security_word"
        android:paddingEnd="18dp"
        android:paddingStart="18dp" />

    <RelativeLayout
        android:id="@+id/container_security"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/container_recycler"
        android:minHeight="150dp"
        android:paddingEnd="18dp"
        android:paddingStart="18dp"

        android:visibility="visible" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/security_container"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/app_name"
        android:minHeight="50dp"
        android:scaleType="centerInside" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>

Bon Chance!