2012-09-16 7 views
14

Tôi chỉ đang cố triển khai bộ chọn màu cho ứng dụng Android của mình và gặp sự cố lạ trên Android 4.1.1. Các mã sau đây không tạo ra các gradient dự kiến ​​trên Android 4.1.1, nhưng nó về 2.3.7:Sự cố với ComposeShader trên Android 4.1.1

Shader fadeInRight = new LinearGradient(0, 0, pWidth, 0, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP); 
Shader blackToWhite = new LinearGradient(0, 0, 0, pHeight, 0xFF000000, 0xFFFFFFFF, Shader.TileMode.CLAMP); 
Shader whiteMask = new ComposeShader(blackToWhite, fadeInRight, PorterDuff.Mode.DST_IN); 
Shader blackToColor = new LinearGradient(0, 0, pWidth, 0, 0xFF000000, hue, Shader.TileMode.CLAMP); 
Shader shader = new ComposeShader(blackToColor, whiteMask, PorterDuff.Mode.SCREEN); 
paint.setShader(shader); 
... 
canvas.drawRect(new Rect(0, 0, pWidth, pHeight), paint); 

Dưới đây là các vấn đề: enter image description here

(bỏ qua các hộp màu đỏ bên dưới trên Android 4.1.1. Tôi chỉ nói về gradient ở trên)

Bất kỳ ý tưởng gì là sai? Tôi nghĩ rằng có cái gì đó thiếu trong mã của tôi, nhưng tôi không có bất kỳ ý tưởng, những gì.

EDIT # 1: Nếu tôi chỉ sử dụng whiteMask cho setShader, tôi cũng có được kết quả khác nhau cho cả hai hệ thống: Trên 2.3.7 Tôi có thể thấy nội dung của menu cấu hình (đó là đằng sau popup) sáng thông qua hình chữ nhật gradient. Hơn nữa có một gradient từ cạnh trên bên trái đến cạnh dưới bên phải (từ đen sang trắng), nhưng gradient trên 4.1.1 đi theo chiều ngang từ trái sang phải. Vì vậy, nó có vẻ là một vấn đề với ComposeShader

EDIT # 2: Tôi tìm thấy một ví dụ đơn giản hơn để mô tả các vấn đề:

Shader shader1 = new LinearGradient(0, 0, 0, pHeight, hue, 0xffffffff, Shader.TileMode.CLAMP); 
Shader shader2 = new LinearGradient(0, 0, pWidth, 0, 0xff000000, 0xffffffff, Shader.TileMode.CLAMP); 
Shader shader = new ComposeShader(shader1, shader2, PorterDuff.Mode.MULTIPLY); 

Vì vậy, chúng tôi chỉ có một gradient tuyến tính dọc từ bất kỳ màu nào sang màu đen và độ dốc tuyến tính ngang từ đen sang trắng. Nếu chúng ta nhân hai lớp này, chúng ta sẽ có được hình chữ nhật chính xác (như trong hình bên trái). Nhưng trên Android 4.1.1 tôi chỉ thấy gradient của shader2. Tôi cũng đã thử điều này trong GIMP với hai lớp và kết quả giống như trên Android 2.3.7.

Trả lời

19

Đã tìm thấy sự cố: Dường như nó phải liên quan đến tăng tốc phần cứng. Như được mô tả here 'ComposeShader chỉ có thể chứa trình bao gồm các loại khác nhau (ví dụ: BitmapShader và LinearGradient, nhưng không có hai phiên bản của BitmapShader)'. Tuy nhiên, 'Nếu ứng dụng của bạn bị ảnh hưởng bởi bất kỳ tính năng hoặc giới hạn bị thiếu nào, bạn có thể tắt tăng tốc phần cứng cho phần bị ảnh hưởng của ứng dụng bằng cách gọi setLayerType(View.LAYER_TYPE_SOFTWARE, null). '

Tôi thấy, rằng phương pháp này là có sẵn từ SDK 11. My App hỗ trợ tất cả các phiên bản bắt đầu với SDK 7, vì vậy tôi phải kiểm tra xem phương pháp này có sẵn:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
    setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
} 

Hiện hành tinh tất cả mọi thứ của.

+0

Gia tốc phần cứng có được áp dụng theo mặc định không? Tôi không tìm thấy thông tin này trong liên kết do bạn cung cấp. – Marek

+0

Không chắc chắn, nhưng tôi nghĩ và hy vọng như vậy :-) –

+2

Ngoài ra còn có 'ViewCompat.setLayerType (xem, View.LAYER_TYPE_SOFTWARE, null);' phương thức/gọi trong thư viện hỗ trợ-v4. – Mavrik