- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
寻找我的问题的解决方案,我必须在环中填充颜色。我可以用我的代码在环中填充颜色,但我遇到了一些问题
使用此代码我无法找到如何在圆圈中填充所需的颜色量,即 20%、40%、70% 等。
当我赋予渐变色时,它与图像中显示的不一样。
我正在使用的代码:
int radius = 130;
CAShapeLayer *arc = [CAShapeLayer layer];
arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100,0) radius:radius startAngle:39.8 endAngle:19.9 clockwise:YES].CGPath;
arc.position = CGPointMake(CGRectGetMidX(self.frame)-radius,
CGRectGetMidY(self.frame)-radius);
arc.fillColor = [UIColor clearColor].CGColor;
arc.strokeColor = [UIColor redColor].CGColor;
arc.lineWidth = 25;
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration = 5.0; // "animate over 10 seconds or so.."
drawAnimation.repeatCount = 1.0; // Animate only once..
drawAnimation.removedOnCompletion = NO; // Remain stroked after the animation..
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue = [NSNumber numberWithFloat:100.0f];
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIColor *gradientColor = [UIColor colorWithRed:0.51 green:0.0 blue:0.49 alpha:1.0];
NSArray *gradientColors = [NSArray arrayWithObjects:
(id)[UIColor blueColor].CGColor,
(id)gradientColor.CGColor,
(id)[UIColor redColor].CGColor, nil];
CGFloat gradientLocations[] = {0, 0.5, 1};
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations);
gradientLayer.colors = (__bridge NSArray *)(gradient);
gradientLayer.startPoint = CGPointMake(0.0,0.7);
gradientLayer.endPoint = CGPointMake(1,-0.1);
[self.layer addSublayer:gradientLayer];
gradientLayer.mask = arc;
重要:颜色必须如图所示
我正在为这个问题寻找非常特殊的答案。
在此先感谢所有有时间调查此事的人。
最佳答案
要用颜色填充一定量的圆圈,您必须在填充层的顶部绘制轮廓并仅剪裁填充层。
为了使渐变跟随圆,你必须将它分成多个分段线性的渐变。由于您提供的图形已经有一些带有轮廓的部分,我们可以使用这些轮廓来隐藏连接不同渐变的任何缺陷。
我举了一个例子,如果你想更好地控制颜色,你可以在 CircleGradientLayer
中为每个段设置它们。通过设置 CircleProgressView
的 progress
属性来控制绘制进度。
如果您在此处看到我的回答:https://stackoverflow.com/a/24580817/3659846,使用两个圆圈和一些线条可以更轻松地绘制轮廓。但是在编写这段代码时,复制和粘贴速度更快;)
.h 文件中没有什么特别的,只是插入编译器想要的内容,我在这里只发布 .m:
CircleProgressView
@implementation CircleProgressView{
CircleGradientLayer *_gradientLayer;
CircleOutlineLayer *_outlineLayer;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
int numSegments = 7;
CGFloat circleRadius = 130;
CGFloat circleWidth = 30;
NSDictionary *circleData = @{
@"numberOfSegments":@(numSegments),
@"circleRadius":@(circleRadius),
@"circleWidth":@(circleWidth)
};
_gradientLayer = [CircleGradientLayer layer];
_gradientLayer.contentsScale = 2;
_gradientLayer.frame = self.bounds;
[_gradientLayer setCircleData:circleData];
[_gradientLayer setNeedsDisplay];
[self.layer addSublayer:_gradientLayer];
_outlineLayer = [CircleOutlineLayer layer];
_outlineLayer.frame = self.bounds;
_outlineLayer.contentsScale = 2;
[_outlineLayer setCircleData:circleData];
[_outlineLayer setNeedsDisplay];
[self.layer addSublayer:_outlineLayer];
self.progress = 1;
}
return self;
}
- (void)setProgress:(CGFloat)progress{
_progress = MAX(0, MIN(1, progress));
_gradientLayer.progress = progress;
}
@end
圆形渐变图层
@implementation CircleGradientLayer{
int _numSegments;
CGFloat _circleRadius;
CGFloat _circleWidth;
CAShapeLayer *_maskLayer;
}
+(id)layer{
CircleGradientLayer *layer = [[CircleGradientLayer alloc] init];
return layer;
}
-(void)setCircleData:(NSDictionary*)data{
_numSegments = [data[@"numberOfSegments"] intValue];
_circleRadius = [data[@"circleRadius"] doubleValue];
_circleWidth = [data[@"circleWidth"] doubleValue];
[self createMask];
}
- (void)createMask{
_maskLayer = [CAShapeLayer layer];
_maskLayer.frame = self.bounds;
CGFloat angleStep = 2*M_PI/(_numSegments+1);
CGFloat startAngle = angleStep/2 + M_PI_2;
CGFloat endAngle = startAngle+_numSegments*angleStep+0.005; //add a bit that the outline is not clipped
_maskLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)) radius:_circleRadius startAngle:startAngle endAngle:endAngle clockwise:YES].CGPath;
_maskLayer.fillColor = [UIColor clearColor].CGColor;
_maskLayer.strokeColor = [UIColor redColor].CGColor;
_maskLayer.lineWidth = 2*_circleWidth+2; //stroke is centered -> *2 to cover all
self.mask = _maskLayer;
}
- (void)setProgress:(CGFloat)progress{
_progress = MAX(0, MIN(1, progress));
_maskLayer.strokeEnd = _progress;
}
-(void)drawInContext:(CGContextRef)ctx{
// would get better gradient joints by not using antialias, but since they are hidden, it is not needed to adjust it
// CGContextSetAllowsAntialiasing(ctx, NO);
UIGraphicsPushContext(ctx);
//some values to adjust the circle
UIColor *startColor = [UIColor colorWithRed:1 green:0 blue:21/255. alpha:1];
UIColor *endColor = [UIColor colorWithRed:0 green:180/255. blue:35/255. alpha:1];
CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
//calculate startAngle and the increment between segements
CGFloat angleStep = 2*M_PI/(_numSegments+1);
CGFloat startAngle = angleStep/2 + M_PI_2;
//convert colors to hsv
CGFloat startHue,startSat,startBrightness,startAlpha;
CGFloat endHue,endSat,endBrightness,endAlpha;
[startColor getHue:&startHue saturation:&startSat brightness:&startBrightness alpha:&startAlpha];
[endColor getHue:&endHue saturation:&endSat brightness:&endBrightness alpha:&endAlpha];
if(endHue<startHue)
endHue+=1;
//draw the segments
for(int i=0;i<_numSegments;i++){
//calcualte segment startColor
CGFloat hue = startHue+((endHue-startHue)*i)/_numSegments;
if(hue>1)
hue-=1;
CGFloat brightness = startBrightness+((endBrightness-startBrightness)*i)/(_numSegments);
if(_numSegments==7){
//just increasing the brighness a bit to get more yellow like on your picture ;)
brightness = i>3?startBrightness+((endBrightness-startBrightness)*(i-4))/(_numSegments-4):startBrightness;
}
UIColor *fromColor = [UIColor colorWithHue:hue saturation:startSat+((endSat-startSat)*i)/_numSegments brightness:brightness alpha:startAlpha+((endAlpha-startAlpha)*i)/_numSegments];
//calculate segement endColor
hue = startHue+((endHue-startHue)*(i+1))/_numSegments;
if(hue>1)
hue-=1;
brightness = startBrightness+((endBrightness-startBrightness)*i)/(_numSegments);
if(_numSegments==7){
brightness = i>3?startBrightness+((endBrightness-startBrightness)*(i-3))/(_numSegments-4):startBrightness;
}
UIColor *toColor = [UIColor colorWithHue:hue saturation:startSat+((endSat-startSat)*(i+1))/_numSegments brightness:brightness alpha:startAlpha+((endAlpha-startAlpha)*(i+1))/_numSegments];
//actually draw the segment
[self drawSegmentAtCenter:centerPoint from:startAngle to:startAngle+angleStep radius:_circleRadius width:_circleWidth startColor:fromColor endColor:toColor];
startAngle+=angleStep;
}
//start clearing the inside
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
UIBezierPath* innerPath = [UIBezierPath bezierPath];
[innerPath moveToPoint:centerPoint];
[innerPath addArcWithCenter:centerPoint radius:_circleRadius-_circleWidth-0.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[innerPath fill];
}
- (void)drawSegmentAtCenter:(CGPoint)center from:(CGFloat)startAngle to:(CGFloat)endAngle radius:(CGFloat)radius width:(CGFloat)width startColor:(UIColor *)startColor endColor:(UIColor*)endColor{
CGContextSaveGState(UIGraphicsGetCurrentContext());
//apply a clip arc for the gradient
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:center];
[path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[path addClip];
//draw the gradient
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = @[(__bridge id) startColor.CGColor, (__bridge id) endColor.CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(center.x-sinf(startAngle-M_PI_2)*radius, center.y+cosf(startAngle-M_PI_2)*radius);
CGPoint endPoint = CGPointMake(center.x-sinf(endAngle-M_PI_2)*radius, center.y+cosf(endAngle-M_PI_2)*radius);
CGContextDrawLinearGradient(UIGraphicsGetCurrentContext(), gradient, startPoint, endPoint, kCGGradientDrawsAfterEndLocation|kCGGradientDrawsBeforeStartLocation);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
CGContextRestoreGState(UIGraphicsGetCurrentContext());
}
@end
圆形轮廓图层
@implementation CircleOutlineLayer{
int _numSegments;
CGFloat _circleradius;
CGFloat _circlewidth;
}
+(id)layer{
CircleOutlineLayer *layer = [[CircleOutlineLayer alloc] init];
return layer;
}
-(void)setCircleData:(NSDictionary*)data{
_numSegments = [data[@"numberOfSegments"] intValue];
_circleradius = [data[@"circleRadius"] doubleValue];
_circlewidth = [data[@"circleWidth"] doubleValue];
}
-(void)drawInContext:(CGContextRef)ctx{
UIGraphicsPushContext(ctx);
//some values to adjust the circle
[[UIColor colorWithWhite:130/255. alpha:1] setStroke]; //the outline color
CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
//calculate startAngle and the increment between segements
CGFloat angleStep = 2*M_PI/(_numSegments+1);
CGFloat startAngle = angleStep/2 + M_PI_2;
//draw the segments
for(int i=0;i<_numSegments;i++){
//actually draw the segment
[self drawSegmentAtCenter:centerPoint from:startAngle to:startAngle+angleStep radius:_circleradius width:_circlewidth doFill:NO];
startAngle+=angleStep;
}
//draw an inner outline
UIBezierPath *innerPath = [UIBezierPath bezierPath];
[innerPath moveToPoint:centerPoint];
[innerPath addArcWithCenter:centerPoint radius:_circleradius-_circlewidth startAngle:0 endAngle:2*M_PI clockwise:YES];
[innerPath stroke];
//start clearing the inside
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
innerPath = [UIBezierPath bezierPath];
[innerPath moveToPoint:centerPoint];
[innerPath addArcWithCenter:centerPoint radius:_circleradius-_circlewidth-0.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[innerPath fill];
//also clear a whole segment at the bottom to get rid of the inner outline
[self drawSegmentAtCenter:centerPoint from:-angleStep/2 + M_PI_2 to:angleStep/2+M_PI_2 radius:_circleradius width:_circlewidth doFill:YES];
//redraw the outlines at begin and end of circle since beginning was just cleared and end-outline hasn't been drawed
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);
CGPoint startPoint = CGPointMake(centerPoint.x+sinf(-angleStep/2)*(_circleradius), centerPoint.y+cosf(-angleStep/2)*(_circleradius));
CGPoint endPoint = CGPointMake(centerPoint.x+sinf(-angleStep/2)*(_circleradius-_circlewidth), centerPoint.y+cosf(-angleStep/2)*(_circleradius-_circlewidth));
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), startPoint.x, startPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), endPoint.x,endPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
startPoint = CGPointMake(centerPoint.x+sinf(angleStep/2)*(_circleradius), centerPoint.y+cosf(angleStep/2)*(_circleradius));
endPoint = CGPointMake(centerPoint.x+sinf(angleStep/2)*(_circleradius-_circlewidth), centerPoint.y+cosf(angleStep/2)*(_circleradius-_circlewidth));
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), startPoint.x, startPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), endPoint.x, endPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
}
- (void)drawSegmentAtCenter:(CGPoint)center from:(CGFloat)startAngle to:(CGFloat)endAngle radius:(CGFloat)radius width:(CGFloat)width doFill:(BOOL)fill{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:center];
[path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
if(fill)
[path fill];
[path stroke];
}
@end
关于ios - 根据百分比用渐变颜色填充圆环。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24751607/
我正在阅读 java swing,但在理解它时遇到问题。 Color 是一个类吗? Color[] col= {Color.RED,Color.BLUE}; 这在java中是什么意思? 最佳答案 Is
我正在研究用 python 编写的 pacman 程序。其中一个模块是处理吃 bean 游戏的图形表示。这当然是一些主机颜色。列表如下: GHOST_COLORS = [] ## establishe
本网站:http://pamplonaenglishteacher.com 源代码在这里:https://github.com/Yorkshireman/pamplona_english_teache
我最近将我的手机更新为 Android Marshmallow 并在其上运行了我现有的应用程序,但注意到颜色行为有所不同:将更改应用到 View (可绘制)的背景时,共享相同背景的所有 View (引
所有 X11/w3c 颜色代码在 Android XML 资源文件格式中是什么样的? I know this looks a tad ridiculous as a question, but giv
试图让 ffmpeg 创建音频波形,同时能够控制图像大小、颜色和幅度。我已经尝试过这个(以及许多变体),但它只是返回无与伦比的 "。 ffmpeg -i input -filter_complex "
我很好奇你是否有一些关于 R 中颜色酿造的技巧,对于许多独特的颜色,以某种方式使图表仍然好看。 我需要大量独特的颜色(至少 24 种,可能需要更多,~50 种)用于堆叠区域图(所以不是热图,渐变色不起
我看到的许多 WPF 示例和示例似乎都有硬编码的颜色。这些指南 - http://msdn.microsoft.com/en-us/library/aa350483.aspx建议不要硬编码颜色。在构建
我想更改文件夹的默认蓝色 如何设置? 最佳答案 :hi Directory guifg=#FF0000 ctermfg=red 关于Vim NERDTree 颜色,我们在Stack Overflow上
是否有关于如何将任意字符串哈希为 RGB 颜色值的最佳实践?或者更一般地说:3 个字节。 你问:我什么时候需要这个?这对我来说并不重要,但想象一下任何 GitHub 上的那些管图 network pa
我正在尝试将默认颜色设置为自定义窗口小部件。 这是有问题的代码。 class ReusableCard extends StatelessWidget { ReusableCard({this.
import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.Ta
我有一个 less 文件来定义一堆颜色/颜色。每个类名都包含相关颜色的名称,例如 .colourOrange{..} 或 .colourBorderOrange{..} 或 navLeftButtOr
我有一个RelativeLayout,我需要一个黑色背景和一个位于其中间的小图像。我使用了这段代码: 其中@drawable/bottom_box_back是: 这样我就可以将图像居中了。但背
我需要设置 浅色 的 JPanel 背景,只是为了不覆盖文本(粗体黑色)。 此刻我有这个: import java.util.Random; .... private Random random =
我正在尝试制作一个自定义文本编辑器,可以更改特定键入单词的字体和颜色。如何更改使用光标突出显示的文本的字体和/或颜色? 我还没有尝试过突出显示部分。我尝试获取整个 hEdit(HWND) 区域并更改字
我想改变我整个应用程序的颜色。 在我的 AndroidManfiest.xml 中,我有正确的代码: 在 values 文件夹中,我有 app_theme.xml: @style/MyAc
是否可以使用 android 数据绑定(bind)从 xml 中引用颜色? 这很好用: android:textColor="@{inputValue == null ? 0xFFFBC02D : 0
有没有办法在 Android 应用程序中设置“空心”颜色? 我的意思是我想要一个带有某种背景的框,而文本实际上会导致背景透明。换句话说,如果整个 View 在蓝色背景上,文本将是蓝色的,如果它是红色的
我用CGContextStrokePath画在白色背景图片中的一条直线上,描边颜色为红色,alpha为1.0画线后,为什么点不是(255, 0, 0),而是(255, 96, 96)为什么不是纯红色?
我是一名优秀的程序员,十分优秀!