[英]Custom preferences in Android that use the correct layout
For custom preferences, eg a time picker preference, I use the following XML in Android: 对于自定义首选项,例如时间选择器首选项,我在Android中使用以下XML:
<com.my.package.TimePreference android:key="notification_time" android:selectable="true" android:title="@string/notification_time" android:enabled="true" android:summary="@string/setTime" android:defaultValue="00:00" />
Where the class "TimePreference" is: “TimePreference”类是:
package com.my.package;
import android.content.Context;
import android.content.res.TypedArray;
import android.preference.DialogPreference;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TimePicker;
public class TimePreference extends DialogPreference {
private int lastHour = 0;
private int lastMinute = 0;
private TimePicker picker = null;
private boolean is_24_hours = true;
public static int getHour(String time) {
String[] pieces = time.split(":");
return(Integer.parseInt(pieces[0]));
}
public static int getMinute(String time) {
String[] pieces = time.split(":");
return(Integer.parseInt(pieces[1]));
}
public TimePreference(Context ctxt) {
this(ctxt, null);
}
public TimePreference(Context ctxt, AttributeSet attrs) {
this(ctxt, attrs, 0);
}
public TimePreference(Context ctxt, AttributeSet attrs, int defStyle) {
super(ctxt, attrs, defStyle);
setPositiveButtonText(ctxt.getString(R.string.save));
setNegativeButtonText(ctxt.getString(R.string.cancel));
try {
is_24_hours = DateFormat.is24HourFormat(ctxt);
}
catch (Exception e) {
is_24_hours = true;
}
}
@Override
protected View onCreateDialogView() {
picker = new TimePicker(getContext());
if (is_24_hours) {
picker.setIs24HourView(true);
}
else {
picker.setIs24HourView(false);
}
return(picker);
}
@Override
protected void onBindDialogView(View v) {
super.onBindDialogView(v);
picker.setCurrentHour(lastHour);
picker.setCurrentMinute(lastMinute);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
picker.clearFocus(); // important - otherwise manual input is not saved
lastHour = picker.getCurrentHour();
lastMinute = picker.getCurrentMinute();
String time = String.valueOf(lastHour)+":"+String.valueOf(lastMinute);
if (callChangeListener(time)) {
persistString(time);
}
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return(a.getString(index));
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
String time = null;
if (restoreValue) {
if (defaultValue == null) {
time = getPersistedString("00:00");
}
else {
time = getPersistedString(defaultValue.toString());
}
}
else {
time = defaultValue.toString();
}
lastHour = getHour(time);
lastMinute = getMinute(time);
}
}
This has always worked great on Android 2.2 and 2.3 - but now that I've switched to Android 4.0 I can see that this preference does not adjust to the preference screen's layout: 这在Android 2.2和2.3上一直运行良好 - 但是现在我已经切换到Android 4.0,我可以看到这个偏好不适应偏好屏幕的布局:
How can I solve this problem? 我怎么解决这个问题? Is there a solution better than setting margin/padding manually? 有没有比手动设置边距/填充更好的解决方案?
Finally found the problem: 终于找到了问题:
The constructor super()
must be called that takes only two arguments (and no int defStyle
argument). 必须调用构造函数super()
,它只接受两个参数(并且没有int defStyle
参数)。
In the code from the question, super()
is called with a predefined defStyle
value of 0
whcih prevents Android from choosing any nice layout. 在问题的代码中,调用super()
预定义的defStyle
值为0
阻止Android选择任何漂亮的布局。 If you call super()
without giving a default style argument, super class DialogPreference
's constructor chooses the best style on its own. 如果在没有给出默认样式参数的情况下调用super()
,超类DialogPreference
的构造函数会自行选择最佳样式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.