【问题标题】:Using DialogPreference in Custom Day Picker在自定义日期选择器中使用 DialogPreference
【发布时间】:2014-04-09 02:19:15
【问题描述】:

我正在尝试显示自定义日期选择器。这是我到目前为止所做的。

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

上面的代码显示了自定义首选项“选择一天”,点击它会显示自定义日期选择器。

除了我不知道如何获取日期选择器中选择的值以及如何将选择的日期选择器值存储在首选项中之外,所有内容都正确显示。

谁能告诉我怎么做?

谢谢!

【问题讨论】:

    标签: android android-intent sharedpreferences android-preferences preferenceactivity


    【解决方案1】:

    您可以通过绑定到 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"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      • 2023-03-30
      • 2020-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多