黑莓用户界面设计 - 可定制的UI?

20

我正在尝试设计一个黑莓应用程序,想知道是否有任何资源可以教授如何创建自定义用户界面元素、皮肤现有的元素以及还有哪些其他可能性?

我已经开发了一些具有自定义UI等内容的iPhone应用程序,不确定BB世界在UI开发方面提供了什么。

任何提示、建议或想法都将非常棒。

3个回答

69

在黑莓中没有皮肤,我知道实现皮肤效果的两种方法是:

  • 创建自己的主题
  • 创建自定义控件

创建黑莓主题

已删除无法访问的 Imageshack 链接 - 黑莓主题构建器

使用主题构建器可以做什么? 它的一些主要功能包括:

  • 自定义黑莓应用程序图标
  • 更改主屏幕横幅图像和图标/指示灯颜色
  • 创建自己的按钮
  • 自定义对话框和弹出屏幕的外观
  • 自定义空闲屏幕
  • 自定义菜单和列表的外观
  • 自定义电话应用程序屏幕
  • 自定义在黑莓设备上使用的字体

如何创建您自己的个性化黑莓主题 by BrileyKenney
bb dev journal - Just Theme It!
黑莓主题和动画图形

坏消息 - 主题适用于整个设备操作系统和每个应用程序
虽然创建的主题可能是一个独立的软件设计产品,但我认为为开发的应用程序创建自己的主题并不是一个好主意。

设计模型

编程GUI可能需要一些时间,如果你想在不编写代码的情况下解决GUI规划中的一些问题,你可能需要绘制GUI模型。

您可以使用ArtfulBits提供的免费黑莓UI原型Visio Stencils-v1.0

已删除死亡的Imageshack链接
已删除死亡的Imageshack链接

创建自定义控件

通过创建自定义控件,您可以配置:

  • 控件大小
  • 控件形状
  • 控件背景(颜色、图像)
  • 控件字体(大小、样式、颜色)
  • 控件边框(大小、样式、颜色)

所有这些都是针对以下状态的:

  • 禁用
  • 正常
  • 聚焦
  • 活动(已单击)

最后,您可以通过设置背景图像来轻松地美化控件

基础知识

devsushi.com:Blackberry JDE API-用户界面字段参考基本上会给出现有的黑莓UI控件的想法,附有代码片段和屏幕截图。

SO:如何将项目添加到ListField(黑莓)
SO:嵌入式HTML控件适用于Blackberry?
SO:Blackberry-如何从DateField获取日期时间值?
SO:将BlackBerry应用程序样式设置为类似iPhone

管理器,布局

即使使用标准控件,我们也需要按照我们想要的方式布局和分组,因此我们需要自定义管理器:
思考黑莓:黑莓UI - 创建基本字段管理器
思考黑莓:简单的黑莓网格布局管理器
思考黑莓:制作自定义屏幕,垂直滚动等
SO:黑莓应用程序中的滚动问题
SO:如何在Blackberry中为VerticalFieldManager设置ScrollBar?
无线电:为屏幕创建自定义布局管理器
SO:Blackberry - 获取控件的所有子字段
SO:取消布局管理器中的滚动
SO:在BlackBerry中创建自定义布局
SO:Blackberry在FullScreen中设置RichtextField的位置
SO:与字段管理器一起玩
SO:黑莓 - 自定义菜单工具栏
SO:BlackBerry - 自定义居中循环HorizontalFieldManager 自定义控件

一组关于编写自定义控件的文章:
思考黑莓:黑莓 UI - 一个简单的自定义字段
Coderholic:Blackberry 自定义按钮字段
无线电:为 BBStorm 创建自己的虚拟键盘
无线电:带有复选框的 ListField
CodeProject:创建作为 BlackBerry 自定义字段的 XY 图表/图形
SO:Blackberry - 自定义大小 EditField
SO:Blackberry - 如何为 BasicEditField 添加边框?
SO:Blackberry - 设置 LabelField 背景颜色
SO:Blackberry 更改水平管理器焦点上子字段的背景和字体颜色
SO:为 RichTextField、TextField 设置背景和字体颜色
SO:Blackberry Java:没有插入符号的 TextField?
SO:Image Map-类似的 Blackberry 控件 - CLDC 应用程序
SO:Blackberry - 单行 BasicEditField,具有大文本
SO:Blackberry - 自定义 BubbleChartField
SO:Blackberry - 从带复选框的列表中获取已选项目
SO:黑莓 - 创建自定义日期字段
SO:黑莓 - 如何创建子菜单?
SO:黑莓 - 如何以编程方式显示带表情符号的标签?
SO:黑莓 - 以编程方式显示输入模式指示器

图形,动画

SO:黑莓-在屏幕上绘制图像
SO:Blackberry-背景图像/动画RIM OS 4.5.0
SO:黑莓-带动画的加载屏幕
SO:如何在Blackberry Storm中设置抗锯齿?
SO:Blackberry设置剪辑区域/区域
SO:在BlackBerry中使用Bitmap还是EncodedImage更好?
SO:黑莓-字段布局动画

字体

无线:更改 BlackBerry 应用程序中的字体
开发人员日志:字体
SO:如何为黑莓应用程序创建自定义字体
SO:如何在 Blackberry 中将字体设置为 LabelField 文本?
SO:如何使 Blackberry UI 更具吸引力?
SO:如何动态更改黑莓标签字段的字体颜色?
SO:BlackBerry - Unicode 文本显示


如果我能再多点赞的话,这篇文章讲解得非常好,感谢@Max Gontar提供的链接,再次感谢... :-) - BBdev
1
@PareshMayani,谢谢你,但请考虑到RIM OS 6和7 UI API中有许多变化和改进。 - Maksym Gontar
@MaxGontar 感谢您的建议。但是您知道我刚刚开始阅读您推荐的那本书。我有一本《Beginning BlackBerry Development(2009)》的副本,这足够好吗? - Paresh Mayani
1
@PareshMayani,对于刚开始来说是正确的,但请记住OS 6.0发布于2010年,OS 7.0发布于2011年 - Maksym Gontar
@MaxGontar 好的,没问题。但是我现在有点困惑,我应该选择哪个平台开始呢? - Paresh Mayani

5

在Bold 9000上使用标准媒体应用程序外观的示例

已删除失效的ImageShack链接 - 切割的媒体应用程序

已删除失效的ImageShack链接 - 切割的图片

使用ButtonField扩展将图像映射到按钮:

class BitmapButtonField extends ButtonField {
    Bitmap mNormal;
    Bitmap mFocused;
    Bitmap mActive;

    int mWidth;
    int mHeight;

    public BitmapButtonField(Bitmap normal, Bitmap focused, 
        Bitmap active) {
        super(CONSUME_CLICK);
        mNormal = normal;
        mFocused = focused;
        mActive = active;
        mWidth = mNormal.getWidth();
        mHeight = mNormal.getHeight();
        setMargin(0, 0, 0, 0);
        setPadding(0, 0, 0, 0);
        setBorder(BorderFactory
                    .createSimpleBorder(new XYEdges(0, 0, 0, 0)));
        setBorder(VISUAL_STATE_ACTIVE, BorderFactory
                .createSimpleBorder(new XYEdges(0, 0, 0, 0)));
    }

    protected void paint(Graphics graphics) {
        Bitmap bitmap = null;
        switch (getVisualState()) {
        case VISUAL_STATE_NORMAL:
            bitmap = mNormal;
            break;
        case VISUAL_STATE_FOCUS:
            bitmap = mFocused;
            break;
        case VISUAL_STATE_ACTIVE:
            bitmap = mActive;
            break;
        default:
            bitmap = mNormal;
        }
        graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(),
                bitmap, 0, 0);
    }

    public int getPreferredWidth() {
        return mWidth;
    }

    public int getPreferredHeight() {
        return mHeight;
    }

    protected void layout(int width, int height) {
        setExtent(mWidth, mHeight);
    }
}
  • 将HorizontalFieldManagers放置在VerticalFieldManagers内,反之亦然
  • 使用不同的图像来表示正常、聚焦和活动状态
  • 如果需要自定义形状的按钮,可以在manager paint()方法覆盖后,在super.paint()之后绘制它们

代码的其余部分:

class Scr extends MainScreen implements FieldChangeListener {
    Bitmap mBmpHeader = Bitmap.getBitmapResource("header.png");
    Bitmap mBmpCover = Bitmap.getBitmapResource("cover.png");
    Bitmap mBmpTitle = Bitmap.getBitmapResource("title.png");
    Bitmap mBmpTimeline = Bitmap.getBitmapResource("timeline.png");
    Bitmap mBmpLeftside = Bitmap.getBitmapResource("leftside.png");
    Bitmap mBmpPrevNrm = Bitmap.getBitmapResource("btn_prev_normal.png");
    Bitmap mBmpPlayNrm = Bitmap.getBitmapResource("btn_play_normal.png");
    Bitmap mBmpPauseNrm = Bitmap.getBitmapResource("btn_pause_normal.png");
    Bitmap mBmpStopNrm = Bitmap.getBitmapResource("btn_stop_normal.png");
    Bitmap mBmpNextNrm = Bitmap.getBitmapResource("btn_next_normal.png");
    Bitmap mBmpPrevFcs = Bitmap.getBitmapResource("btn_prev_focused.png");
    Bitmap mBmpPlayFcs = Bitmap.getBitmapResource("btn_play_focused.png");
    Bitmap mBmpPauseFcs = Bitmap.getBitmapResource("btn_pause_focused.png");
    Bitmap mBmpStopFcs = Bitmap.getBitmapResource("btn_stop_focused.png");
    Bitmap mBmpNextFcs = Bitmap.getBitmapResource("btn_next_focused.png");
    Bitmap mBmpRightside = Bitmap.getBitmapResource("rightside.png");
    VerticalFieldManager mMainManager;
    HorizontalFieldManager mHeaderManager;
    HorizontalFieldManager mCoverManager;
    HorizontalFieldManager mTitleManager;
    HorizontalFieldManager mTimelineManager;
    HorizontalFieldManager mToolbarManager;
    BitmapField mHeader;
    BitmapField mCover;
    BitmapField mTitle;
    BitmapField mTimeline;
    BitmapField mLeftside;
    BitmapField mRightside;
    BitmapButtonField mBtnPrev;
    BitmapButtonField mBtnPlay;
    BitmapButtonField mBtnPause;
    BitmapButtonField mBtnStop;
    BitmapButtonField mBtnNext;
    public Scr() {
        add(mMainManager = new VerticalFieldManager());
        addHeader();
        addCover();
        addTitle();
        addTimeline();
        addToolbar();
    }
    private void addHeader() {
        mMainManager.add(mHeaderManager = new HorizontalFieldManager());
        mHeaderManager.add(mHeader = new BitmapField(mBmpHeader));
    }
    private void addCover() {
        mMainManager.add(mCoverManager = new HorizontalFieldManager());
        mCoverManager.add(mCover = new BitmapField(mBmpCover));
    }
    private void addTitle() {
        mMainManager.add(mTitleManager = new HorizontalFieldManager());
        mTitleManager.add(mTitle = new BitmapField(mBmpTitle));
    }
    private void addTimeline() {
        mMainManager.add(mTimelineManager = new HorizontalFieldManager());
        mTimelineManager.add(mTimeline = new BitmapField(mBmpTimeline));
    }
    private void addToolbar() {
        mMainManager.add(mToolbarManager = new HorizontalFieldManager());
        mToolbarManager.add(mLeftside = new BitmapField(mBmpLeftside));
        mToolbarManager.add(mBtnPrev = new BitmapButtonField(mBmpPrevNrm,
                mBmpPrevFcs, mBmpPrevFcs));
        mToolbarManager.add(mBtnPlay = new BitmapButtonField(mBmpPlayNrm,
                mBmpPlayFcs, mBmpPlayFcs));
        mBtnPlay.setChangeListener(this);
        mBtnPause = new BitmapButtonField(mBmpPauseNrm, mBmpPauseFcs,
                mBmpPauseFcs);
        mBtnPause.setChangeListener(this);
        mToolbarManager.add(mBtnStop = new BitmapButtonField(mBmpStopNrm,
                mBmpStopFcs, mBmpStopFcs));
        mToolbarManager.add(mBtnNext = new BitmapButtonField(mBmpNextNrm,
                mBmpNextFcs, mBmpNextFcs));
        mToolbarManager.add(mRightside = new BitmapField(mBmpRightside));
    }
    public void fieldChanged(Field field, int context) {
        if (mBtnPlay == field)
            play();
        else if (mBtnPause == field)
            pause();
    }
    private void pause() {
        mToolbarManager.replace(mBtnPause, mBtnPlay);
    }
    private void play() {
        mToolbarManager.replace(mBtnPlay, mBtnPause);
    }
}

如果我们使用BorderFactory,我们必须导入哪个类? - Bohemian
我猜是net.rim.device.api.ui.decor.BackgroundFactory。但是在eclipse 4.5插件中不可用。有什么线索吗? - Bohemian
是的,它在4.6以下版本不可用,请使用位图皮肤参见https://dev59.com/H0jSa4cB1Zd3GeqPFXOE - Maksym Gontar
顺便说一下,Max,ArtfulBits已经发布了适用于BlackBerry 10设备的新的黑莓UI原型Visio Stencils。你参加了吗?http://www.artfulbits.com/products/blackberry/prototyping.aspx 这很不错。我用这个工具构建了几个屏幕。非常简单易用。 - user2091719

4

这些 资源 很不好,遗憾的是。通常最好的信息来源是谷歌链接到具有您寻找的特定主题的博客。

如果您刚开始编写BB GUI代码,我强烈建议您先了解ManagerField类,因为您可能需要编写许多自定义扩展。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接