Android 给信的一部分涂颜色最好的方法是什么?
我想实现这样的目标:Android 给信的一部分涂颜色最好的方法是什么?,android,Android,我想实现这样的目标: public class ProgressTextView extends TextView { private static final float MAX_PROGRESS = ...; private Paint mPaint; public ProgressTextView(Context context) { super(context); initPaint(); } /* othe
public class ProgressTextView extends TextView {
private static final float MAX_PROGRESS = ...;
private Paint mPaint;
public ProgressTextView(Context context) {
super(context);
initPaint();
}
/* other constructor omitted, but do the same pattern in those */
private void initPaint() {
mPaint = new Paint();
mPaint.setColor(...);
mPaint.setXfermode(new PorterDuffXfermode(Mode.XOR));
// note: you may also need the following line if hardware accel is available
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawProgress(canvas);
}
private void drawProgress(Canvas canvas) {
int w = getWidth() - getPaddingLeft() - getPaddingRight();
int h = getHeight() - getPaddingTop() - getPaddingBottom();
float progress = getProgress();
float rectW = w * (progress / MAX_PROGRESS);
int saveCount = canvas.save();
canvas.translate(getPaddingLeft(), getPaddingTop());
canvas.drawRect(0, 0, rectW, h, mPaint);
canvas.restoreToCount(saveCount);
}
private float getProgress() {
// TODO
}
}
首先想到的是在画布上画两次文本,并用形状覆盖第一个文本。但是也许有更好的解决方案。对于纯android解决方案来说,您的方法听起来不错,但是我在这里要做的有点非传统,建议您将UI的这一部分转换为HTML组件web视图,并使用HTML css解决方案,因为这种渲染要容易得多。不确定这是否是纯粹主义者的理想解决方案,但听起来确实很容易做到。检查这个我试图重新创建UI的工作示例(只需点击运行代码片段,或检查最后的JSFIDLE链接):
函数条宽度(){
var barWidth=$('.progress bar').width();
$('.progress fill text').css('width',barWidth);
}
条宽();
window.onresize=函数(){
条宽();
}
。进度条{
背景:#ccc;
颜色:#7d7d7d;
填充:10px0;
宽度:100%;
文本对齐:居中;
位置:相对位置;
字体大小:40px;
字体系列:“开放式Sans”,无衬线;
}
.进度填写{
背景:#0095dd;
颜色:#fff;
宽度:47%;
填充:10px0;
位置:绝对位置;
左:0;
排名:0;
溢出:隐藏;
}
.进度填写文本{
}
37个单位
37个单位
一种方法是使用PorterDuffXfermode
在文本上合成蓝色矩形。您可以扩展TextView
并覆盖onDraw()
以在绘制文本后绘制矩形,并且使用适当的模式(我相信XOR
就是您想要的模式)应该可以达到所需的效果。大概是这样的:
public class ProgressTextView extends TextView {
private static final float MAX_PROGRESS = ...;
private Paint mPaint;
public ProgressTextView(Context context) {
super(context);
initPaint();
}
/* other constructor omitted, but do the same pattern in those */
private void initPaint() {
mPaint = new Paint();
mPaint.setColor(...);
mPaint.setXfermode(new PorterDuffXfermode(Mode.XOR));
// note: you may also need the following line if hardware accel is available
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawProgress(canvas);
}
private void drawProgress(Canvas canvas) {
int w = getWidth() - getPaddingLeft() - getPaddingRight();
int h = getHeight() - getPaddingTop() - getPaddingBottom();
float progress = getProgress();
float rectW = w * (progress / MAX_PROGRESS);
int saveCount = canvas.save();
canvas.translate(getPaddingLeft(), getPaddingTop());
canvas.drawRect(0, 0, rectW, h, mPaint);
canvas.restoreToCount(saveCount);
}
private float getProgress() {
// TODO
}
}
有关Porter/Duff合成的更多信息:在web环境中可能很理想,但当您需要通过视图结构控制内容时就不行了。即使使用web视图,您也可以通过Java代码控制web视图。考虑到这一点,你所要做的就是在进度条中的CSS中更改<代码>宽度>代码> PARAM。现在,如果你再编写一点JavaScript,从URL读取宽度,从Android代码中,你可以不断更新web视图的JavaScript路径,你就有了一个动态组件。是的,你可以,但主要的问题是,对于这么简单的东西来说,这似乎有些过分了。另外,让我们假设应该有一个动画如何在内容上需要渲染/动画,除非你是一个网络专家,使动画更专注于Web组件。我并不是说这是不可能的,我只是说,对于一个应用程序(在android中)来说,使用这样的东西可能更需要维护成本,而这个应用程序在任何方面都不可能是面向网络的。在所有方面,我都同意你的看法。这只是我建议的另一种选择。我想这要归结为编写和维护本机渲染的复杂程度,而不是实现html组件的成本。我想知道是否还有其他解决方案。如果某人的应用程序是面向web的,那么无论哪种方式+1都绝对是一个很好的方法:)这应该是一个进度条吗?或者只是突出显示了数字?听起来你想要的是
paint.setXfermode(新的PorterDuffXfermode(PorterDuff.Mode.XOR))代码>查看此问题了解更多信息:注意:我在@theFunkyEngineer发表评论之前就开始写此答案,但他链接的帖子也很有用。这看起来方向正确,但当我使用Mode.XOR时,它会删除rect和文本,我尝试过其他模式,但没有成功。@IvanFork尝试使用调试器,并确保绘图在正确的坐标下进行。也许可以删除Paint
上的Xfermode
,看看它是否在正确的位置绘制。另外,其中有一个注释行调用视图上的setLayerType()
,您可能需要取消注释以使其正常工作。您是否测试了代码?如果有效,您可以提供xml吗?我尝试过使用所有PorterDuff模式的多种方法,但遗憾的是它们都不起作用,通常文本会随着rect完全剪切。最后,我使用canvas.clipRect再次绘制了文本的后半部分。@IvanFork我不得不取消对setLayerType()
调用的注释,但除此之外,它的工作方式与使用XOR
时的预期完全相同。