2013-01-24 91 views
1

如何在BlackBerry中繪製徑向漸變按鈕?我在BlackBerry支持論壇上找到了「Drawing Radial Gradients」。我能夠自己實現的是線性漸變。在黑莓中繪製徑向漸變?

+1

您發現有代碼,徑向漸變,這是你所要求的鏈接。該解決方案以何種方式不足? –

+0

@MichaelDonohue我試過這段代碼,即時獲取不同的顏色不梯度。但我需要確切的徑向漸變。 – David

回答

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

要使用此,包含該按鈕將需要限制按鈕的尺寸在其sublayout()實施Manager。或者,您可以編輯我的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 遮罩圖像(在您喜歡的繪圖程序中)可能是最容易的,該圖像大部分是透明的,然後只是填充了遮蓋角落的角落在它下面的梯度。然後,在上面的paint()方法中使用Graphics.drawBitmap(),在之後使用您已經繪製了徑向漸變。

爲了突出顯示焦點,我只是放了一些簡單的代碼來使按鈕聚焦時的顏色變亮。再一次,你沒有說出你想要的,所以我只是做了一些簡單的事情。

以上是上述代碼的結果。底部的按鍵集中:

enter image description here