我正在尝试显示自定义日期选择器。这是我到目前为止所做的。
menu_settings.xml:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="@string/pref_user_profile" >
<com.example.DatePickerDialogPreference
android:dialogLayout="@layout/date_time_dialog"
android:key="prefDayPicker"
android:title="Pick a Day"
android:summary="Day Picker"
android:positiveButtonText="Set"
android:negativeButtonText="Cancel" />
</PreferenceCategory>
</PreferenceScreen>
date_time_dialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/DateTimeDialog"
android:layout_width="277dp"
android:layout_height="217dp"
android:background="#999999" >
<com.example.customdatepicker.DateTimePicker
android:id="@+id/DateTimePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true" />
</RelativeLayout>
datetimepicker.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/DateTimePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:padding="5dip" >
<LinearLayout
android:layout_width="277dp"
android:layout_height="153dp"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:background="#000000"
android:baselineAligned="true"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/date_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<Button
android:id="@+id/date_plus"
android:layout_width="74dp"
android:layout_height="41dp"
android:background="@drawable/image_button_up" />
<EditText
android:id="@+id/date_display"
android:layout_width="74dp"
android:layout_height="49dp"
android:background="@drawable/picker_middle"
android:gravity="center"
android:inputType="number"
android:padding="1dp"
android:singleLine="true"
android:textColor="#000000"
android:textSize="28sp" />
<Button
android:id="@+id/date_minus"
android:layout_width="74dp"
android:layout_height="41dp"
android:background="@drawable/image_button_down" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
DayTimePicker.java:
public class DateTimePicker extends RelativeLayout {
private View myPickerView;
private Button date_plus;
private EditText date_display;
private Button date_minus;
private Calendar cal;
public DateTimePicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DateTimePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myPickerView = inflator.inflate(R.layout.datetimepicker, null);
this.addView(myPickerView);
initializeReference();
}
private void init(Context mContext) {
LayoutInflater inflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myPickerView = inflator.inflate(R.layout.datetimepicker, null);
this.addView(myPickerView);
initializeReference();
}
private void initializeReference() {
date_plus = (Button) myPickerView.findViewById(R.id.date_plus);
date_plus.setOnClickListener(date_plus_listener);
date_display = (EditText) myPickerView.findViewById(R.id.date_display);
date_display.addTextChangedListener(date_watcher);
date_minus = (Button) myPickerView.findViewById(R.id.date_minus);
date_minus.setOnClickListener(date_minus_listener);
initData();
initFilterNumericDigit();
}
public void initData() {
cal = Calendar.getInstance();
date_display.setText(String.valueOf(cal.get(Calendar.DAY_OF_MONTH)));
}
private void initFilterNumericDigit() {
try {
date_display.setFilters(new InputFilter[] { new InputFilterMinMax(1, cal.getActualMaximum(Calendar.DAY_OF_MONTH)) });
} catch (Exception e) {
e.printStackTrace();
}
}
private void changeFilter() {
try {
date_display.setFilters(new InputFilter[] { new InputFilterMinMax(1, cal.getActualMaximum(Calendar.DAY_OF_MONTH)) });
} catch (Exception e) {
date_display.setText("" + cal.get(Calendar.DAY_OF_MONTH));
e.printStackTrace();
}
}
public void setTimeChangedListener(TimeWatcher listener) {
this.mTimeWatcher = listener;
}
public void removeTimeChangedListener() {
this.mTimeWatcher = null;
}
View.OnClickListener date_plus_listener = new View.OnClickListener() {
public void onClick(View v) {
try {
date_display.requestFocus();
cal.add(Calendar.DAY_OF_MONTH, 1);
date_display.setText(String.valueOf(cal.get(Calendar.DAY_OF_MONTH)));
sendToListener();
} catch (Exception e) {
e.printStackTrace();
}
}
};
View.OnClickListener date_minus_listener = new View.OnClickListener() {
public void onClick(View v) {
try {
date_display.requestFocus();
cal.add(Calendar.DAY_OF_MONTH, -1);
date_display.setText(String.valueOf(cal.get(Calendar.DAY_OF_MONTH)));
sendToListener();
} catch (Exception e) {
e.printStackTrace();
}
}
};
class InputFilterMinMax implements InputFilter {
private int min, max;
public InputFilterMinMax(int min, int max) {
this.min = min;
this.max = max;
}
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString()
+ source.toString());
if (isInRange(min, max, input)) {
return null;
}
} catch (NumberFormatException nfe) {
}
return "";
}
private boolean isInRange(int a, int b, int c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}
public void reset() {
cal = Calendar.getInstance();
initFilterNumericDigit();
initData();
}
synchronized private void sendToListener() {
if (mDateWatcher != null) {
mDateWatcher.onDateChanged(cal);
}
}
public int getDay() {
return Integer.parseInt(date_display.getText().toString());
}
public void setDateChangedListener(DateWatcher listener) {
this.mDateWatcher = listener;
}
public void removeDateChangedListener() {
this.mDateWatcher = null;
}
TextWatcher date_watcher = new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
try {
if (s.toString().length() > 0) {
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(s.toString()));
sendToListener();
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
};
DateWatcher mDateWatcher = null;
}
DatePickerDialogPreference.java:
public class DatePickerDialogPreference extends DialogPreference {
public DatePickerDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
// HERE, HOW DO I GET VALUES OF SELECTED DAY FROM CUSTOM DAY PICKER????
// Tried Dialog dialog = getDialog(); But it returns null, so can't do much.
persistBoolean(positiveResult);
}
}
上面的代码显示了自定义首选项“选择一天”,单击其中显示自定义日期选择器。
除了我不知道如何获取在日期选择器中选择的值之外,所有内容都正确显示。如何在首选项中存储选定的日期选择器值。
任何人都可以告诉我该怎么做吗?
谢谢!
答案 0 :(得分:0)
您可以通过绑定PreferenceActivity中的值更改事件来执行此操作,例如 -
/**
* A preference value change listener that updates the preference's summary
* to reflect its new value.
*/
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();
if (preference instanceof RingtonePreference) {
// For ringtone preferences, look up the correct display value
// using RingtoneManager.
if (TextUtils.isEmpty(stringValue)) {
// Empty values correspond to 'silent' (no ringtone).
preference.setSummary(R.string.pref_ringtone_silent);
} else {
Ringtone ringtone = RingtoneManager.getRingtone(
preference.getContext(), Uri.parse(stringValue));
if (ringtone == null) {
// Clear the summary if there was a lookup error.
preference.setSummary(null);
} else {
// Set the summary to reflect the new ringtone display
// name.
String name = ringtone
.getTitle(preference.getContext());
preference.setSummary(name);
}
}
} else {
// For all other preferences, set the summary to the value's
// simple string representation.
preference.setSummary(stringValue);
}
return true;
}
};
/**
* Binds a preference's summary to its value. More specifically, when the
* preference's value is changed, its summary (line of text below the
* preference title) is updated to reflect the value. The summary is also
* immediately updated upon calling this method. The exact display format is
* dependent on the type of preference.
*
* @see #sBindPreferenceSummaryToValueListener
*/
private static void bindPreferenceSummaryToValue(Preference preference) {
// Set the listener to watch for value changes.
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
// Trigger the listener immediately with the preference's
// current value.
String defaultSharedPrefs = PreferenceManager.getDefaultSharedPreferences(preference.getContext()).getString(preference.getKey(), "");
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, defaultSharedPrefs);
}
然后,在构建首选项列表时,注册需要此绑定的控件 -
bindPreferenceSummaryToValue(findPreference("pack_first_pill"));