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

alt text

有帮助吗?

解决方案

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

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

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

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

更新

风暴支持

在带有滚轮的设备上,很容易在导航单击时实现保存并关闭功能,但在 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

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

其他提示

5.0 API 中引入了一个新字段,称为 SpinBox字段管理器. 。对于您的具体情况,还有一个 日期时间选择器 仅适用于日期/时间。对于 5.0 之前的操作系统,您需要创建自己的自定义控件。

这是最大的信息发表评论(没有足够的学分发表评论这样的答案都行)

如果您使用的是被告知他的职位,日历被硬编码为31天每月。

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

代替31应该使用:

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top