1

如何在 BlackBerry 中绘制径向渐变按钮?我在 BlackBerry 支持论坛上找到了“绘制径向渐变”。我能够自己实现的只是线性渐变。

4

1 回答 1

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()方法。

对于焦点突出显示,我只是输入了一些简单的代码来在按钮获得焦点时使颜色变亮。再说一次,你没有说你想要什么,所以我只是做了一些简单的事情。

这是上面代码的结果。底部按钮被聚焦:

在此处输入图像描述

于 2013-01-25T09:08:47.997 回答