BlackBerry - 创建自定义日期字段

发布于 2024-08-15 03:52:31 字数 227 浏览 9 评论 0 原文

我想创建一个看起来像这样的字段....任何人都可以告诉我如何做到这一点,我可以使用哪个字段,在哪里我可以使用轨迹球/滚轮选择值,或者在暴风雨的情况下我可以滑动。 ..

替代文本

i want to create a field that looks like this ....can any one tell me how this could be done which field could i use where in i can select values by using the trackball/wheel or in case of storm i could slide...

alt text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掐死时间 2024-08-22 03:52:31

它可以是简单的标签或位图字段扩展,具有导航事件处理功能。

您需要保存字符串数组,其值将在水平导航时以圆圈形式更改。
如果这样的自定义字段是焦点,则绘制向上和向下数组。

因此,将有一个这样的字段用于 DayOfWeek,一个用于 Month,一个用于 DayOfMonth,一个用于 Year。

将它们全部放置在 Horizo​​ntalFieldManager 中,该管理器将放置在 PopupScreen 中,在弹出窗口关闭时收集所有值并组成日期值(可以通过 FieldChangeListener 传递)

更新

Storm 支持

在带有滚轮的设备上,很容易实现保存 -导航单击时的并关闭功能,但在 Storm 中这将是一个问题(对话框将在每个字段焦点操作上关闭)。为了解决这个问题,添加了“确定”和“取消”按钮。

此外,还添加了 touchEvent 以使用触摸单击来处理适当的值更改。

您可以为 RIM OS <= 4.6 和 RIM OS >= 4.7 保留不同的实现,并在构建任务中替换它们。

来源

替代文本 http://img519.imageshack.us/img519/7312/8300.png 替代文本 http://img267.imageshack.us/img267/6245/ 9000.jpg
替代文本 http://img9.imageshack.us/img9/9098/9530.png< /a>

class DatePickerDialog extends PopupScreen implements FieldChangeListener {

    DatePickerField mDatePicker;
    ButtonField mOKButton;
    ButtonField mCancelButton;

    public DatePickerDialog(Date date) {
        super(new VerticalFieldManager(), PopupScreen.DEFAULT_CLOSE);
        add(mDatePicker = new DatePickerField(date));

        // comment on RIM OS < 4.7
        addButtons();
    }

    private void addButtons() {
        HorizontalFieldManager hfm = new HorizontalFieldManager(FIELD_HCENTER);
        add(hfm);
        mOKButton = new ButtonField("OK", ButtonField.CONSUME_CLICK);
        mOKButton.setChangeListener(this);
        hfm.add(mOKButton);
        mCancelButton = new ButtonField("Cancel", ButtonField.CONSUME_CLICK);
        mCancelButton.setChangeListener(this);
        hfm.add(mCancelButton);
    }

    public void setDate(Date dateValue) {
        mDatePicker.setDate(dateValue);
    }

    public Date getDate() {
        return mDatePicker.getDate();
    }

    public DatePickerDialog() {
        this(Calendar.getInstance().getTime());
    }

    // comment on RIM OS < 4.7
    public void fieldChanged(Field field, int context) {
        if (mOKButton == field) {
            getChangeListener().fieldChanged(this, 0);
            close();
        } else if (mCancelButton == field) {
            close();
        }
    }

    // comment on RIM OS > 4.6
    // protected boolean navigationClick(int status, int time) {
    // getChangeListener().fieldChanged(this, 0);
    // close();
    // return super.navigationClick(status, time);
    // }

    class DatePickerField extends HorizontalFieldManager implements
            FieldChangeListener {
        private String[] daysOfWeek = new String[] { "Sunday", "Monday",
                "Tuesday", "Wednesday", "Thursday", "Friday", 
                "Saturday" };
        private String[] months = new String[] { "Jan", "Feb", "Mar", "Apr",
                "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", 
                "Dec" };
        private int mDayOfMonth = 10;
        private int mMonth = 1;
        private int mYear = 2009;

        private StrTimeField mDayOfWeekField;
        private StrTimeField mMonthField;
        private NumTimeField mDayOfMonthField;
        private NumTimeField mYearField;
        Calendar calendar = Calendar.getInstance();

        public DatePickerField(Date date) {
            calendar.setTime(date);
            mYear = calendar.get(Calendar.YEAR);
            // Calendar.JANUARY == 0, so +1 value
            mMonth = calendar.get(Calendar.MONTH);
            mDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            // think it's better to disable Day Of Week edit
            mDayOfWeekField = new StrTimeField(daysOfWeek, dayOfWeek - 1,
                    NON_FOCUSABLE);
            mDayOfWeekField.setChangeListener(this);
            add(mDayOfWeekField);
            mMonthField = new StrTimeField(months, mMonth);
            mMonthField.setChangeListener(this);
            add(mMonthField);
            mDayOfMonthField = new NumTimeField(mDayOfMonth, 1, 31);
            mDayOfMonthField.setChangeListener(this);
            add(mDayOfMonthField);
            mYearField = new NumTimeField(mYear, 1900, 2012);
            mYearField.setChangeListener(this);
            add(mYearField);
        }

        public void fieldChanged(Field field, int context) {
            mDayOfMonth = mDayOfMonthField.getValue();
            calendar.set(calendar.DAY_OF_MONTH, mDayOfMonth);
            mMonth = mMonthField.getValue();
            calendar.set(calendar.MONTH, mMonth);
            mYear = mYearField.getValue();
            calendar.set(calendar.YEAR, mYear);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
            mDayOfWeekField.setIndex(dayOfWeek);
        }

        public Date getDate() {
            return calendar.getTime();
        }

        public void setDate(Date date) {
            calendar.setTime(date);
            mYear = calendar.get(Calendar.YEAR);
            mMonth = calendar.get(Calendar.MONTH);
            mDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            mDayOfWeekField.setIndex(dayOfWeek - 1);
            mMonthField.setIndex(mMonth);
            mDayOfMonthField.setValue(mDayOfMonth);
            mYearField.setValue(mYear);
        }

        abstract class TimeField extends LabelField {
            int mWidth = 0;

            public TimeField() {
                super("", FOCUSABLE);
            }

            public TimeField(long style) {
                super("", style);
            }

            protected abstract void switchValue(int step);

            protected boolean navigationMovement(int dx, int dy, 
                    int status, int time) {
                if (Math.abs(dy) > Math.abs(dx)) {
                    switchValue(-dy);
                return true;
                } else
                    return super.navigationMovement(dx, dy, status, time);
            }

            boolean prepared = false;

            protected void onFocus(int direction) {
                prepared = false;
                super.onFocus(direction);
            }

            protected void onUnfocus() {
                invalidate();
                super.onUnfocus();
            }

            // comment on RIM OS < 4.7
            protected boolean touchEvent(TouchEvent msg) {
                if (isFocus() && msg.getEvent() == TouchEvent.CLICK) {
                    if (!prepared) {
                        prepared = true;
                    } else {
                        int y = msg.getY(1);
                        int cy = getTop() + (getHeight() >> 1);
                        switchValue((y > cy) ? -1 : 1);
                    }
                }
                return false;
            }

            public int getPreferredWidth() {
                return mWidth;
            }

            public int getPreferredHeight() {
                return super.getPreferredHeight() + 24;
            }

            protected void layout(int width, int height) {
                super.layout(width, height);
                setExtent(getPreferredWidth(), getPreferredHeight());
            }

            protected void paint(Graphics graphics) {
                String text = getText();
                Font font = getFont();
                int x = (getPreferredWidth() 
                    - font.getAdvance(text)) >> 1;
                int y = (getPreferredHeight() - font.getHeight()) >> 1;
                graphics.drawText(text, x, y);
                if (isFocus()) {
                    graphics.setColor(Color.WHITE);
                    int xc = (getPreferredWidth() >> 1);
                    int y1 = 10, y2 = 0, x2 = xc - 9, x1 = xc + 9;

                    int[] xPts = new int[] { x1, x2, xc };
                    int[] yPts = new int[] { y1, y1, y2 };
                    graphics.drawFilledPath(xPts, yPts, 
                        null, null);

                    y2 = getPreferredHeight();
                    y1 = y2 - 10;

                    yPts = new int[] { y1, y1, y2 };
                    graphics.drawFilledPath(xPts, yPts, 
                        null, null);
                }
            }

            public abstract int getValue();
        }

        class StrTimeField extends TimeField {
            String[] mValues;
            int mIndex;

            public StrTimeField(String[] values) {
                this(values, 0);
            }

            public StrTimeField(String[] values, int value) {
                this(values, value, FOCUSABLE);
            }

            public StrTimeField(String[] values, int value, long style) {
                super(style);
                mValues = values;
                setIndex(value);
                Font font = getFont();
                for (int i = 0; i < mValues.length; i++) {
                    int width = font.getAdvance(mValues[i]);
                    mWidth = Math.max(mWidth, width);
                }
                mWidth += 10;
            }

            protected void switchValue(int step) {
                int index = mIndex + step;
                if (index < 0 || index >= mValues.length)
                    index += ((index > 0) ? -1 : 1) 
                        * mValues.length;
                setIndex(index);
            }

            private void setIndex(int index) {
                if (index >= 0 && index < mValues.length) {
                    mIndex = index;
                    setText(mValues[mIndex]);
                }
            }

            public int getValue() {
                return mIndex;
            }

        }

        class NumTimeField extends TimeField {
            int mValue;
            int mMinValue;
            int mMaxValue;

            public NumTimeField(int val, int minVal, int maxVal) {
                this(val, minVal, maxVal, FOCUSABLE);
            }

            public NumTimeField(int val, int minVal, int maxVal,
                    long style) {
                super(style);
                mValue = val;
                mMinValue = minVal;
                mMaxValue = maxVal;

                setText(String.valueOf(mValue));
                int maxDig = String.valueOf(mMaxValue).length();
                String test = "";
                for (int i = 0; i < maxDig; i++)
                    test += "0";
                mWidth = getFont().getAdvance(test);
                mWidth += 10;
            }

            protected void switchValue(int step) {
                int value = mValue + step;
                if (value > mMaxValue)
                    value = value - (mMaxValue - mMinValue + 1);
                if (value < mMinValue)
                    value = value + (mMaxValue - mMinValue + 1);
                setValue(value);
            }

            private void setValue(int value) {
                mValue = value;
                setText(String.valueOf(mValue));
            }

            public int getValue() {
                return mValue;
            }
        }
    }
}

It could be simple Label or Bitmap Field extention, with navigation event handling.

You will need to hold String array with values which will be changed in circle on horizontal navigation.
If such custom Field is focused, draw Up and Down arrays.

So, there will be one such Field for DayOfWeek, one for Month, one for DayOfMonth, one for Year.

Place them all in HorizontalFieldManager, which will be placed in PopupScreen, on popup close geather all values and compose Date value (may be passed over FieldChangeListener)

UPDATE

Storm support

On devices with wheel its easy to implement save-and-close functionality on navigation click, but in Storm that would be a problem (dialog will be closed on each field focus action). To solve this, OK and Cancel buttons added.

Also, touchEvent added to handle proper value change using touch click.

You may keep different implementations for RIM OS <= 4.6 and RIM OS >= 4.7, and replace them on build task.

Source

alt text http://img519.imageshack.us/img519/7312/8300.pngalt text http://img267.imageshack.us/img267/6245/9000.jpg
alt text http://img9.imageshack.us/img9/9098/9530.png

class DatePickerDialog extends PopupScreen implements FieldChangeListener {

    DatePickerField mDatePicker;
    ButtonField mOKButton;
    ButtonField mCancelButton;

    public DatePickerDialog(Date date) {
        super(new VerticalFieldManager(), PopupScreen.DEFAULT_CLOSE);
        add(mDatePicker = new DatePickerField(date));

        // comment on RIM OS < 4.7
        addButtons();
    }

    private void addButtons() {
        HorizontalFieldManager hfm = new HorizontalFieldManager(FIELD_HCENTER);
        add(hfm);
        mOKButton = new ButtonField("OK", ButtonField.CONSUME_CLICK);
        mOKButton.setChangeListener(this);
        hfm.add(mOKButton);
        mCancelButton = new ButtonField("Cancel", ButtonField.CONSUME_CLICK);
        mCancelButton.setChangeListener(this);
        hfm.add(mCancelButton);
    }

    public void setDate(Date dateValue) {
        mDatePicker.setDate(dateValue);
    }

    public Date getDate() {
        return mDatePicker.getDate();
    }

    public DatePickerDialog() {
        this(Calendar.getInstance().getTime());
    }

    // comment on RIM OS < 4.7
    public void fieldChanged(Field field, int context) {
        if (mOKButton == field) {
            getChangeListener().fieldChanged(this, 0);
            close();
        } else if (mCancelButton == field) {
            close();
        }
    }

    // comment on RIM OS > 4.6
    // protected boolean navigationClick(int status, int time) {
    // getChangeListener().fieldChanged(this, 0);
    // close();
    // return super.navigationClick(status, time);
    // }

    class DatePickerField extends HorizontalFieldManager implements
            FieldChangeListener {
        private String[] daysOfWeek = new String[] { "Sunday", "Monday",
                "Tuesday", "Wednesday", "Thursday", "Friday", 
                "Saturday" };
        private String[] months = new String[] { "Jan", "Feb", "Mar", "Apr",
                "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", 
                "Dec" };
        private int mDayOfMonth = 10;
        private int mMonth = 1;
        private int mYear = 2009;

        private StrTimeField mDayOfWeekField;
        private StrTimeField mMonthField;
        private NumTimeField mDayOfMonthField;
        private NumTimeField mYearField;
        Calendar calendar = Calendar.getInstance();

        public DatePickerField(Date date) {
            calendar.setTime(date);
            mYear = calendar.get(Calendar.YEAR);
            // Calendar.JANUARY == 0, so +1 value
            mMonth = calendar.get(Calendar.MONTH);
            mDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            // think it's better to disable Day Of Week edit
            mDayOfWeekField = new StrTimeField(daysOfWeek, dayOfWeek - 1,
                    NON_FOCUSABLE);
            mDayOfWeekField.setChangeListener(this);
            add(mDayOfWeekField);
            mMonthField = new StrTimeField(months, mMonth);
            mMonthField.setChangeListener(this);
            add(mMonthField);
            mDayOfMonthField = new NumTimeField(mDayOfMonth, 1, 31);
            mDayOfMonthField.setChangeListener(this);
            add(mDayOfMonthField);
            mYearField = new NumTimeField(mYear, 1900, 2012);
            mYearField.setChangeListener(this);
            add(mYearField);
        }

        public void fieldChanged(Field field, int context) {
            mDayOfMonth = mDayOfMonthField.getValue();
            calendar.set(calendar.DAY_OF_MONTH, mDayOfMonth);
            mMonth = mMonthField.getValue();
            calendar.set(calendar.MONTH, mMonth);
            mYear = mYearField.getValue();
            calendar.set(calendar.YEAR, mYear);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
            mDayOfWeekField.setIndex(dayOfWeek);
        }

        public Date getDate() {
            return calendar.getTime();
        }

        public void setDate(Date date) {
            calendar.setTime(date);
            mYear = calendar.get(Calendar.YEAR);
            mMonth = calendar.get(Calendar.MONTH);
            mDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            mDayOfWeekField.setIndex(dayOfWeek - 1);
            mMonthField.setIndex(mMonth);
            mDayOfMonthField.setValue(mDayOfMonth);
            mYearField.setValue(mYear);
        }

        abstract class TimeField extends LabelField {
            int mWidth = 0;

            public TimeField() {
                super("", FOCUSABLE);
            }

            public TimeField(long style) {
                super("", style);
            }

            protected abstract void switchValue(int step);

            protected boolean navigationMovement(int dx, int dy, 
                    int status, int time) {
                if (Math.abs(dy) > Math.abs(dx)) {
                    switchValue(-dy);
                return true;
                } else
                    return super.navigationMovement(dx, dy, status, time);
            }

            boolean prepared = false;

            protected void onFocus(int direction) {
                prepared = false;
                super.onFocus(direction);
            }

            protected void onUnfocus() {
                invalidate();
                super.onUnfocus();
            }

            // comment on RIM OS < 4.7
            protected boolean touchEvent(TouchEvent msg) {
                if (isFocus() && msg.getEvent() == TouchEvent.CLICK) {
                    if (!prepared) {
                        prepared = true;
                    } else {
                        int y = msg.getY(1);
                        int cy = getTop() + (getHeight() >> 1);
                        switchValue((y > cy) ? -1 : 1);
                    }
                }
                return false;
            }

            public int getPreferredWidth() {
                return mWidth;
            }

            public int getPreferredHeight() {
                return super.getPreferredHeight() + 24;
            }

            protected void layout(int width, int height) {
                super.layout(width, height);
                setExtent(getPreferredWidth(), getPreferredHeight());
            }

            protected void paint(Graphics graphics) {
                String text = getText();
                Font font = getFont();
                int x = (getPreferredWidth() 
                    - font.getAdvance(text)) >> 1;
                int y = (getPreferredHeight() - font.getHeight()) >> 1;
                graphics.drawText(text, x, y);
                if (isFocus()) {
                    graphics.setColor(Color.WHITE);
                    int xc = (getPreferredWidth() >> 1);
                    int y1 = 10, y2 = 0, x2 = xc - 9, x1 = xc + 9;

                    int[] xPts = new int[] { x1, x2, xc };
                    int[] yPts = new int[] { y1, y1, y2 };
                    graphics.drawFilledPath(xPts, yPts, 
                        null, null);

                    y2 = getPreferredHeight();
                    y1 = y2 - 10;

                    yPts = new int[] { y1, y1, y2 };
                    graphics.drawFilledPath(xPts, yPts, 
                        null, null);
                }
            }

            public abstract int getValue();
        }

        class StrTimeField extends TimeField {
            String[] mValues;
            int mIndex;

            public StrTimeField(String[] values) {
                this(values, 0);
            }

            public StrTimeField(String[] values, int value) {
                this(values, value, FOCUSABLE);
            }

            public StrTimeField(String[] values, int value, long style) {
                super(style);
                mValues = values;
                setIndex(value);
                Font font = getFont();
                for (int i = 0; i < mValues.length; i++) {
                    int width = font.getAdvance(mValues[i]);
                    mWidth = Math.max(mWidth, width);
                }
                mWidth += 10;
            }

            protected void switchValue(int step) {
                int index = mIndex + step;
                if (index < 0 || index >= mValues.length)
                    index += ((index > 0) ? -1 : 1) 
                        * mValues.length;
                setIndex(index);
            }

            private void setIndex(int index) {
                if (index >= 0 && index < mValues.length) {
                    mIndex = index;
                    setText(mValues[mIndex]);
                }
            }

            public int getValue() {
                return mIndex;
            }

        }

        class NumTimeField extends TimeField {
            int mValue;
            int mMinValue;
            int mMaxValue;

            public NumTimeField(int val, int minVal, int maxVal) {
                this(val, minVal, maxVal, FOCUSABLE);
            }

            public NumTimeField(int val, int minVal, int maxVal,
                    long style) {
                super(style);
                mValue = val;
                mMinValue = minVal;
                mMaxValue = maxVal;

                setText(String.valueOf(mValue));
                int maxDig = String.valueOf(mMaxValue).length();
                String test = "";
                for (int i = 0; i < maxDig; i++)
                    test += "0";
                mWidth = getFont().getAdvance(test);
                mWidth += 10;
            }

            protected void switchValue(int step) {
                int value = mValue + step;
                if (value > mMaxValue)
                    value = value - (mMaxValue - mMinValue + 1);
                if (value < mMinValue)
                    value = value + (mMaxValue - mMinValue + 1);
                setValue(value);
            }

            private void setValue(int value) {
                mValue = value;
                setText(String.valueOf(mValue));
            }

            public int getValue() {
                return mValue;
            }
        }
    }
}
情归归情 2024-08-22 03:52:31

5.0 API 中引入了一个名为 SpinBoxFieldManager。对于您的具体情况,还有一个 DateTimePicker 仅适用于日期/时间。对于 5.0 之前的操作系统,您需要创建自己的自定义控件。

There is a new field introduced in the 5.0 API called SpinBoxFieldManager. For your specific case, there is also a DateTimePicker just for dates/times. For operating systems prior to 5.0, you'll need to create your own custom controls.

妄司 2024-08-22 03:52:31

这是对 Max 帖子的评论(没有足够的积分来发表评论,所以回答即可)

如果您正在使用他的帖子,请注意,日历针对每个有 31 天的月份进行了硬编码。

<代码>
mDayOfMonthField = new NumTimeField(mDayOfMonth, 1, 31);

而不是 31,您应该使用:

net.rim.device.api.util.DateTimeUtilities.getNumberOfDaysInMonth(month,year);

This is a comment to Max's post (not enough credits to post a comment so answer will do)

If you are using his post be advised that the calendar is being hard coded for every month having 31 days.


mDayOfMonthField = new NumTimeField(mDayOfMonth, 1, 31);

Instead of 31 you should use:

net.rim.device.api.util.DateTimeUtilities.getNumberOfDaysInMonth(month, year);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文