如何在 BlackBerry 中绘制径向渐变按钮?我在 BlackBerry 支持论坛上找到了“绘制径向渐变”。我能够自己实现的只是线性渐变。
1 回答
这有点棘手。在字段背景上绘制线性渐变很容易。在场背景上绘制径向渐变更难。在按钮上执行此操作更加困难。
首先,您链接到的示例确实看起来很糟糕。该代码的最大问题是它使用Graphics.drawArc()
同心圆(线)构建渐变。这一点都不顺利。
您需要做出的最大改进是Graphics.fillArc()
改用它,它看起来会更流畅(尽管这可能会对性能产生影响......)。
您的问题没有说明您希望按钮在聚焦时的外观,或者是否需要圆角。这就是一些困难所在。
如果您只是扩展 RIMButtonField
类,您可能会遇到焦点和边缘效果的默认绘图问题。可能有必要Field
在一个新的、从头开始编写的按钮字段中直接扩展基类。我不一定建议您自己做所有这些,因为按钮需要焦点处理、单击处理等。您可能应该从 BlackBerry AdvancedUI 开源库中的BaseButtonField之类的东西开始。
我已经为你做了这个原型,使用那个类作为基础。(因此,如果您使用它,您需要下载该源文件并将其包含在您的项目中)。
我创建了一个 GradientButtonField 子类:
private class GradientButtonField extends BaseButtonField {
private int startR;
private int startG;
private int startB;
private int endR;
private int endG;
private int endB;
/** the maximum distance from the field's center, in pixels */
private double rMax = -1.0;
private int width;
private int height;
private String label;
private int fontColor;
/**
* Create a gradient button field
* @param startColor the integer Color code to use at the button center
* @param endColor the integer Color code to use at the button edges
* @param label the text to show on the button
* @param fontColor color for label text
*/
public GradientButtonField (int startColor, int endColor, String label, int fontColor) {
// record start and end color R/G/B components, to
// make intermediate math easier
startR = (startColor >> 16) & 0xFF;
startG = (startColor >> 8) & 0xFF;
startB = startColor & 0xFF;
endR = (endColor >> 16) & 0xFF;
endG = (endColor >> 8) & 0xFF;
endB = endColor & 0xFF;
this.label = label;
this.fontColor = fontColor;
}
public String getLabel() {
return label;
}
protected void layout(int w, int h) {
width = Math.min(Display.getWidth(), w);
height = Math.min(Display.getHeight(), h);
if (rMax < 0.0) {
rMax = Math.sqrt((width * width)/4.0 + (height * height)/4.0);
}
setExtent(width, height);
}
private int getColor(double scale, boolean highlighted) {
int r = (int)(scale * (endR - startR)) + startR;
int g = (int)(scale * (endG - startG)) + startG;
int b = (int)(scale * (endB - startB)) + startB;
if (highlighted) {
// just brighten the color up a bit
r = (int)Math.min(255, r * 1.5);
g = (int)Math.min(255, g * 1.5);
b = (int)Math.min(255, b * 1.5);
}
return (65536 * r + 256 * g + b);
}
protected void paint(Graphics graphics) {
int oldColor = graphics.getColor();
// we must loop from the outer edge, in, to draw
// concentric circles of decreasing radius, and
// changing color
for (int radius = (int)rMax; radius >= 0; radius--) {
double scale = ((double)radius) / rMax;
boolean focused = (getVisualState() == Field.VISUAL_STATE_FOCUS);
graphics.setColor(getColor(scale, focused));
int x = width / 2 - radius;
int y = height / 2 - radius;
graphics.fillArc(x, y, 2 * radius, 2 * radius, 0, 360);
}
String text = getLabel();
graphics.setColor(fontColor);
graphics.drawText(text,
(width - getFont().getAdvance(text)) / 2,
(height - getFont().getHeight()) / 2);
// reset graphics object
graphics.setColor(oldColor);
}
}
要使用它,Manager
包含按钮的 将需要在其sublayout()
实现中限制按钮的大小。或者,您可以编辑我的GradientButtonField
课程以硬编码特定大小(通过getPreferredWidth()
、layout()
等)或您想要的任何内容。
final Field button1 = new GradientButtonField(Color.DARKGRAY, Color.BLUE,
"Click Me!", Color.WHITE);
final Field button2 = new GradientButtonField(Color.DARKGRAY, Color.BLUE,
"Click Me, Too!", Color.WHITE);
Manager mgr = new Manager(Manager.NO_VERTICAL_SCROLL) {
public int getPreferredHeight() {
return Display.getHeight();
}
public int getPreferredWidth() {
return Display.getWidth();
}
protected void sublayout(int maxWidth, int maxHeight) {
setExtent(getPreferredWidth(), getPreferredHeight());
layoutChild(button1, 160, 80);
setPositionChild(button1, 20, 50);
layoutChild(button2, 120, 60);
setPositionChild(button2, 20, 150);
}
};
button1.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
Dialog.alert("clicked!");
}
});
mgr.add(button1);
mgr.add(button2);
add(mgr);
我没有拐弯抹角,因为这有点工作。根据您将这些按钮放在什么样的背景上,创建一个 PNG蒙版图像(在您最喜欢的绘图程序中)可能是最简单的,它大部分是透明的,然后只是填充了遮盖角落的角落它下面的渐变。然后,在绘制径向渐变之后,使用Graphics.drawBitmap()
上述paint()
方法。
对于焦点突出显示,我只是输入了一些简单的代码来在按钮获得焦点时使颜色变亮。再说一次,你没有说你想要什么,所以我只是做了一些简单的事情。
这是上面代码的结果。底部按钮被聚焦: