Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DialogPreference in Full Screen Width

Tags:

android

I created a custom dialog preference in my Android application, but I can not figure out how to get the dialog which is displayed to span the complete width of the display.

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

I found many proposed solutions to get a normal Dialog in full screen mode

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

But setting the attributes via getWindow does not work:

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

And applying a full screen theme to my dialogs root element didn't do the job neither:

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

Moreover I'm not able to access the onCreate Method (at least I don't know how) of the Dialog, to set the style there.

Did anyone had the same problem and figured out a solution for this very specific issue?

My layout:

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

My custom preference class

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

Edit:

Actually I only want the dialog to span over the full width of the screen, not the height. If I would use a additional PreferenceFragment (as the DialogPreference is already embedded in a PreferenceFragment ) the "Dialog" (aka Fragment) would take the complete width and height (i guess).

I already implemented a solution without a DialogPrefrence, that works but is not exactly elegant

  • using just a normal EditTextPreference
  • adding an onPreferenceClickListener to this preference in my SettingsFragment Code
    • the ClickListener displays a simple Dialog

Example:

        Preference preference = findPreference(EXAMPLE_PREFRENCE);    

        if (preference != null) {

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

But as I have a lot of preferences which will display dialogs the code for the dialog creation and display bloads the SettingsFragment and makes it nearly unreadable. Therefore I thought it would be a nice solution to put the responsibility of displaying the dialog and handling the preference values to the Preference and the XML layout.

Unfortunately I got stuck with the "full width issue" mentioned above.

Note: fixed the code of getDialog as I tested different versions (also in combination with the xml theme set)

like image 322
little_planet Avatar asked May 03 '26 19:05

little_planet


1 Answers

Finally I did find a solution for this problem:

Fetch the AlertDialog of the Preference in showDialog method

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

make it span the complete width:

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);
        }
    }
}
like image 125
little_planet Avatar answered May 06 '26 10:05

little_planet