Câu hỏi này vẫn còn hiệu lực gần như vào giữa năm 2017. Tôi muốn tạo chuyển đổi suôn sẻ cho các thay đổi màu cho chế độ xem tùy chỉnh của mình. Tôi đã sử dụng shaders với LinearGradients.
Ý định của tôi là làm cho quá trình chuyển đổi suôn sẻ betweeen trạng thái vô hiệu hóa và bị tắt trong chế độ xem của tôi.
Trường hợp của tôi thậm chí còn phức tạp hơn do xây dựng và mục đích của chế độ xem. Đó là một thanh trượt. Vì vậy, quan điểm của tôi bao gồm gần 2 lớp giống hệt nhau được vẽ trên đầu trang của lớp thứ hai sử dụng canvas. Yếu tố thứ ba là một con trỏ.
Cả hai lớp đều sử dụng LinearGradients, con trỏ sử dụng một màu duy nhất.
Tổng hợp tất cả tôi phải làm một sự chuyển tiếp giữa 5 màu sắc cùng một lúc:
- bắt đầu và màu cuối cho đáy lớp - một Gradient Linear,
- bắt đầu và kết thúc màu cho lớp trên cùng - Gradient Linear thứ hai ,
- màu con trỏ - màu bình thường;
Giải pháp cho điều này là có 5 Trình tạo giá trị riêng biệt. Điều quan trọng nhất là sử dụng ValueAnimator.ofArgb():
private ValueAnimator frontStartColorAnimator;
private ValueAnimator frontEndColorAnimator;
private ValueAnimator bottomStartColorAnimator;
private ValueAnimator bottomEndColorAnimator;
private ValueAnimator pointerColorAnimator;
private AnimatorSet colorsAnimatorSet;
...
frontStartColorAnimator = ValueAnimator.ofArgb(frontLayerStartColor, frontLayerDisabledStartColor);
frontStartColorAnimator.setDuration(animationDuration);
frontStartColorAnimator.setInterpolator(new LinearInterpolator());
frontStartColorAnimator.addUpdateListener(animation
-> shaderFrontLayerStartColor = (int) animation.getAnimatedValue());
frontEndColorAnimator = ValueAnimator.ofArgb(frontLayerEndColor, frontLayerDisabledEndColor);
frontEndColorAnimator.setDuration(animationDuration);
frontEndColorAnimator.setInterpolator(new LinearInterpolator());
frontEndColorAnimator.addUpdateListener(animation -> {
shaderFrontLayerEndColor = (int) animation.getAnimatedValue();
frontLayerPaint.setShader(new LinearGradient(0, 0, getWidth(), 0, shaderFrontLayerStartColor,
shaderFrontLayerEndColor, Shader.TileMode.CLAMP));
});
bottomStartColorAnimator = ValueAnimator.ofArgb(bottomLayerStartColor, bottomLayerDisabledStartColor);
bottomStartColorAnimator.setDuration(animationDuration);
bottomStartColorAnimator.setInterpolator(new LinearInterpolator());
bottomStartColorAnimator.addUpdateListener(animation ->
shaderBottomLayerStartColor = (int) animation.getAnimatedValue());
bottomEndColorAnimator = ValueAnimator.ofArgb(bottomLayerEndColor, bottomLayerDisabledEndColor);
bottomEndColorAnimator.setDuration(animationDuration);
bottomEndColorAnimator.setInterpolator(new LinearInterpolator());
bottomEndColorAnimator.addUpdateListener(animation -> {
shaderBottomLayerEndColor = (int) animation.getAnimatedValue();
backLayerPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), shaderBottomLayerStartColor,
shaderBottomLayerEndColor, Shader.TileMode.CLAMP));
});
pointerColorAnimator = ValueAnimator.ofArgb(pointerEnabledColor, pointerDisabledColor);
pointerColorAnimator.setDuration(animationDuration);
pointerColorAnimator.setInterpolator(new LinearInterpolator());
pointerColorAnimator.addUpdateListener(animation -> {
pointerColor = (int) animation.getAnimatedValue();
pointerPaint.setColor(pointerColor);
});
colorsAnimatorSet = new AnimatorSet();
colorsAnimatorSet.playTogether(frontStartColorAnimator, frontEndColorAnimator,
bottomStartColorAnimator, bottomEndColorAnimator, pointerColorAnimator);
...
colorsAnimatorSet.start();
Tôi cũng lo ngại khi khởi về việc tạo một Gradient Linear mới trên mỗi lần cập nhật hình ảnh động nhưng sau đó tôi đưa ra GPU hồ sơ trên điện thoại với "Trên màn hình là thanh" . Mọi thứ đều ổn và chạy trong lề an toàn.
Cảm ơn Romain, bạn có thể chia sẻ kiến thức chuyên môn của mình trong nhận xét của tôi về cắm trại dưới đây không? Tôi tự hỏi phương thức .draw() nào hiệu quả nhất sẽ là vẽ hai lớp cần thiết để tạo hiệu ứng này hoặc nếu LayerDrawable chính xác là cái tôi cần. – Greg
@Romain Guy Tôi đã cố gắng sử dụng SweepGradient để đạt được hiệu ứng gradient hình nón.Nhưng có vẻ như nó chỉ hoạt động với hai màu. Nếu tôi sử dụng một mảng bốn màu thì ** SweepGradient ** dường như không hoạt động như mong đợi. Tôi đã thử kết hợp khác nhau của ** vị trí ** giá trị và cũng đã cố gắng cài đặt vị trí như ** NULL ** nhưng hầu hết tôi chỉ nhận được hai màu hoặc một gradient mà không phải là hình nón. Bất kì sự trợ giúp nào đều được đánh giá cao. –