我正在尝试绘制一个由渐变填充的圆弧
下图就是我想要的
下图是我现在的样子
正如你在图片中看到的,我的渐变开始得太早了
我知道为什么会这样
如果我完成圆弧形成一个圆,我会得到这个
正如我们所见,渐变从 90 度开始。 但是我的弧度是从135度画出来的,扫到270度
我的问题是如何让渐变从 135 度开始扫到 270 度?可以吗
到目前为止,这是我进行扫描渐变的方法
public void setProgressColourAsGradient(boolean invalidateNow) {
SweepGradient sweepGradient = new SweepGradient(baseArcRect.centerX(), baseArcRect.centerY(),progressGradientColourStart,progressGradientColourEnd);
//Make the gradient start from 90 degrees
Matrix matrix = new Matrix();
matrix.setRotate(90,baseArcRect.centerX(), baseArcRect.centerY());
sweepGradient.setLocalMatrix(matrix);
progressFillPaint.setShader(sweepGradient);
if (invalidateNow) {
invalidate();
}
}
我找不到任何 API 来告诉 SweepGradient 从哪里开始。
我已将所有代码添加到附录部分
感谢阅读!
评论 1
我尝试将旋转设置为 135 度
附录A ArcWithGradient View
public class ArcWithGradient extends View {
private Paint progressFillPaint;
private RectF baseArcRect;
private int progressGradientColourStart;
private int progressGradientColourEnd;
/**
* Thickness of the arc
*/
private int thickness;
public ArcWithGradient(Context context) {
super(context);
init();
}
public ArcWithGradient(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ArcWithGradient(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
progressGradientColourStart = ContextCompat.getColor(getContext(), R.color.pinnacle_gradient_start);
progressGradientColourEnd = ContextCompat.getColor(getContext(), R.color.pinnacle_gradient_end);
thickness = UiUtils.dpToPx(getContext(), 25);
//We do not want a colour for this because we will set a gradient
progressFillPaint = CanvasUtil.makeStrokePaint(UiUtils.dpToPx(getContext(), 25), -1);
baseArcRect = new RectF(0, 0, 0, 0);
setProgressColourAsGradient(false);
}
@Override
protected void onSizeChanged(int width, int height, int oldw, int oldh) {
super.onSizeChanged(width, height, oldw, oldh);
//Ensures arc is within the rectangle
float radius = Math.min(width, height) / 2;//
//I do radius - thickness so that the arc is within the rectangle
float baseArcLeft = ((width / 2) - (radius - thickness));
float baseArcTop = ((height / 2) - (radius - thickness));
float baseArcRight = ((width / 2) + (radius - thickness));
float baseArcBottom = ((height / 2) + (radius - thickness));
baseArcRect.set(baseArcLeft, baseArcTop, baseArcRight, baseArcBottom);
//Recalculate the gradient
setProgressColourAsGradient(false);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawArc(baseArcRect, 135, 270, false, progressFillPaint);
}
public void setProgressColourAsGradient(boolean invalidateNow) {
SweepGradient sweepGradient = new SweepGradient(baseArcRect.centerX(), baseArcRect.centerY(),progressGradientColourStart,progressGradientColourEnd);
//Make the gradient start from 90 degrees
Matrix matrix = new Matrix();
matrix.setRotate(90,baseArcRect.centerX(), baseArcRect.centerY());
sweepGradient.setLocalMatrix(matrix);
progressFillPaint.setShader(sweepGradient);
if (invalidateNow) {
invalidate();
}
}
}
附录 B UiUtils
public class UiUtils {
public static int dpToPx(Context ctx, float dp) {
return Math.round(dp * ctx.getResources().getDisplayMetrics().density);
}
}
附录 C CanvasUtil
public class CanvasUtil {
public static Paint makeStrokePaint(int width, int color) {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.SQUARE);
paint.setStrokeWidth(width);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(color);
return paint;
}
public static Paint makeFillPaint(int color) {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
return paint;
}
最佳答案
正如@pskink 在评论中提到的,您需要使用SweepGradient 构造函数,它接受一个颜色列表和一个位置列表。 positions 参数是一个 float 数组,指示颜色应开始的 360 度百分比。
在我的示例中,我将 Canvas 旋转 115 度,然后为我的拱形绘制一个 310 度的扫描角。第一种颜色从 0 度角开始(因为 Canvas 已旋转),渐变以 310 度角到达第二种颜色,因此它与拱形的扫描角相匹配。外圈显示蓝色一直持续到 360 度,但蓝色从 310 度开始。
class SweepGradientView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
): View(context, attrs, defStyleAttr) {
private val archPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.STROKE
strokeWidth = 32 * context.resources.displayMetrics.density
}
private val archBounds = RectF()
private val archInset = 72 * context.resources.displayMetrics.density
private val gradientColors = intArrayOf(Color.MAGENTA, Color.BLUE)
private val gradientPositions = floatArrayOf(0/360f, 310/360f)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
val size = Math.min(width, height)
setMeasuredDimension(size, size)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
archPaint.shader = SweepGradient(width / 2f, height / 2f, gradientColors, gradientPositions)
archBounds.set(archInset, archInset, width.toFloat() - archInset, height.toFloat() - archInset)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
canvas.save()
canvas.rotate(115f, cx, cy)
canvas.drawArc(archBounds, 0f, 310f, false, archPaint)
canvas.drawCircle(cx, cy, width / 2.2f, archPaint)
canvas.restore()
}
}
关于java - Android:Canvas Arc,Sweep Gradient Start Angle可以改吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44504601/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www