如何在BlackBerry中绘制径向渐变按钮?我在BlackBerry支持论坛上找到了“Drawing Radial Gradients”。我能够自己实现的是线性渐变。
答案 0 :(得分:1)
这有点棘手。在场地背景上绘制线性渐变很容易。在场背景上绘制径向渐变更难。在按钮上执行操作更难。
首先,您链接到的示例确实看起来非常糟糕。该代码的最大问题是它使用Graphics.drawArc()
来构造同心圆(线)之外的渐变。这根本不顺利。
您需要做的最大改进是使用Graphics.fillArc()
代替,这看起来会更顺畅(尽管可能会对此产生性能影响......)。
您的问题没有说明在聚焦时您希望按钮看起来如何,或者角落是否需要四舍五入。这就是一些困难所在。
如果你只是扩展RIM ButtonField
类,你可能会遇到焦点和边缘效果的默认绘图。可能需要在一个新的,从头开始编写的按钮字段中直接扩展基类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()
,在之后使用绘制径向渐变。
对于焦点突出显示,我只需输入一些简单的代码即可在按钮聚焦时使颜色变亮。再一次,你没有说出你想要的东西,所以我只是做了一些简单的事情。
这是上面代码的结果。底部按钮是聚焦的: