2012-01-27 51 views
21

Tôi đang cố gắng tạo một cung (số độ biến) dần dần chuyển từ màu này sang màu khác. Từ ví dụ từ màu xanh sang màu đỏ:

enter image description hereAndroid - Cách vẽ một đường viền dựa trên gradient

Đây là mã của tôi:

SweepGradient shader = new SweepGradient(center.x, center.y, resources.getColor(R.color.startColor),resources.getColor(R.color.endColor)); 
Paint paint = new Paint() 
paint.setStrokeWidth(1); 
paint.setStrokeCap(Paint.Cap.FILL); 
paint.setStyle(Paint.Style.FILL); 
paint.setShader(shader); 
canvas.drawArc(rectF, startAngle, sweepAngle, true, paint); 

Nhưng kết quả là toàn bộ vòng cung được sơn cùng màu.

Edit:
Sau khi thử nghiệm nhiều hơn, tôi phát hiện ra rằng sự lây lan màu được xác định bởi góc của hồ quang. Nếu tôi vẽ một vòng cung với một góc nhỏ, chỉ có màu đầu tiên được hiển thị. Góc lớn hơn, nhiều màu hơn được vẽ. Nếu góc nhỏ thì có vẻ như không có độ dốc.
Đây là một ví dụ. Tôi vẽ 4 vòng cung - 90, 180, 270 và 360:

RectF rect1 = new RectF(50, 50, 150, 150); 
Paint paint1 = new Paint(); 
paint1.setStrokeWidth(1); 
paint1.setStrokeCap(Paint.Cap.SQUARE); 
paint1.setStyle(Paint.Style.FILL); 

SweepGradient gradient1 = new SweepGradient(100, 100, 
     Color.RED, Color.BLUE); 
paint1.setShader(gradient1); 

canvas.drawArc(rect1, 0, 90, true, paint1); 

RectF rect2 = new RectF(200, 50, 300, 150); 
Paint paint2 = new Paint(); 
paint2.setStrokeWidth(1); 
paint2.setStrokeCap(Paint.Cap.SQUARE); 
paint2.setStyle(Paint.Style.FILL); 

SweepGradient gradient2 = new SweepGradient(250, 100, 
     Color.RED, Color.BLUE); 
paint2.setShader(gradient2); 

canvas.drawArc(rect2, 0, 180, true, paint2); 

RectF rect3 = new RectF(50, 200, 150, 300); 
Paint paint3 = new Paint(); 
paint3.setStrokeWidth(1); 
paint3.setStrokeCap(Paint.Cap.SQUARE); 
paint3.setStyle(Paint.Style.FILL); 

SweepGradient gradient3 = new SweepGradient(100, 250, 
     Color.RED, Color.BLUE); 
paint3.setShader(gradient3); 

canvas.drawArc(rect3, 0, 270, true, paint3); 

RectF rect4 = new RectF(200, 200, 300, 300); 
Paint paint4 = new Paint(); 
paint4.setStrokeWidth(1); 
paint4.setStrokeCap(Paint.Cap.SQUARE); 
paint4.setStyle(Paint.Style.FILL); 

SweepGradient gradient4 = new SweepGradient(250, 250, 
     Color.RED, Color.BLUE); 
paint4.setShader(gradient4); 

canvas.drawArc(rect4, 0, 360, true, paint4); 

Và đây là kết quả:

enter image description here

Đây là đáng ngạc nhiên vì tôi mong đợi RED để có mặt tại bắt đầu của vòng cung, BLUE ở cuối và enything giữa được lây lan đồng đều bất kể góc.
Tôi cố gắng để không gian màu sắc bằng tay bằng cách sử dụng tham số vị trí nhưng kết quả đều như nhau:

int[] colors = {Color.RED, Color.BLUE}; 
float[] positions = {0,1}; 
SweepGradient gradient = new SweepGradient(100, 100, colors , positions); 

Bất kỳ ý tưởng làm thế nào để giải quyết này?

Trả lời

27

Giải pháp cho việc này là đặt vị trí của BLUE. Này được thực hiện như sau:

int[] colors = {Color.RED, Color.BLUE}; 
float[] positions = {0,1}; 
SweepGradient gradient = new SweepGradient(100, 100, colors , positions); 

Vấn đề ở đây là khi thiết lập vị trí của màu xanh để '1' này không có nghĩa là nó sẽ được bố trí ở phần cuối của vòng cung rút ra, nhưng thay vì ở cuối của vòng tròn trong đó cung tròn là một phần của. Để giải quyết điều này, vị trí XANH nên tính đến số độ trong vòng cung. Vì vậy, nếu tôi vẽ một vòng cung với độ X, vị trí sẽ được thiết lập như sau:

float[] positions = {0,Xf/360f}; 

Vì vậy, nếu X là 90, gradient sẽ đặt màu xanh ở 0,25 của vòng tròn:

enter image description here

+1

Ít nhất trên Android 4.2, giải pháp như được đưa ra không hoạt động.Cần có giá trị 1 ở cuối mảng. Một cái gì đó như thế này: int [] colors = {Color.RED, Color.BLUE, Color.BLUE}; float [] positions = {0, Xf/360f, 1}; –

+0

Bạn có biết tại sao độ phân giải rất tệ nếu góc rất nhỏ? giống như chiều rộng hồ quang 10 độ có nghĩa là chỉ 3 màu. Bạn có thể xem các bước cũng trong ảnh chụp màn hình của bạn trong bánh topleft –

9

Để thêm vào giải pháp của Yoav.

Trên Galaxy Nexus 4.2 Android của tôi, giải pháp được cung cấp không hoạt động.

Nếu mảng không chứa 0,0f và 1.0f, nó dường như bị bỏ qua.

giải pháp cuối cùng của tôi là:

int[] colors = {Color.RED, Color.BLUE, Color.RED}; 
float[] positions = {0, Xf/360f, 1}; 
1

lăm năm sau, nhưng đúng cách là làm cho 0.749f với 0.750f của dòng riêng biệt, mã đơn giản giống như:

val colors = intArrayOf(0xffff0000.toInt(), 0xff0000ff.toInt(), 0xffff0000.toInt(), 0xffff0000.toInt()) 
    val positions = floatArrayOf(0.0f, 0.749f, 0.750f, 1.0f) 
+0

cảm ơn bạn đã đăng Kotlin – rundavidrun

Các vấn đề liên quan