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