使用canvas / Ondraw以指定速率进行动画
在我的 Android 应用程序中,我尝试逐个显示字母,每个字母之间有短暂的延迟,同时为每个字母播放声音。我一切正常,声音以正确的延迟播放,但文本总是太快地打印到屏幕上。即使我没有专门使视图无效,画布似乎也会更新。
这是我到目前为止所得到的 - 我还尝试了基于“蛇”示例的变体,并得到了相同的结果......任何帮助将不胜感激!
public class SpellingView extends View {
private static final String WORD = "TRUCK";
int width;
int height;
String textToPrint;
float textspace;
int j=0;
private final Path arc;
private final Paint tPaint;
//constructor for SpellingView
public SpellingView(Context context) {
super(context);
arc = new Path();
tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
displayLetterLoop();
}
public void displayLetterLoop(){
for (int i = 0; i < WORD.length(); i++){
final Runnable mUpdateUITimerTask = new Runnable() {
public void run() {
Spelling.mp.start();
}
};
final Handler mHandler = new Handler();
mHandler.postDelayed(mUpdateUITimerTask, i*1500);
}
}
@Override
protected void onDraw(Canvas canvas) {
int k;
// Drawing commands go here
width = canvas.getWidth();
height = canvas.getHeight();
arc.addArc(new RectF((width*.15f), (height*.15f), (width*.85f), (height*.4f)), 180,180);
tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
tPaint.setColor(Color.RED);
tPaint.setTextSize(height * 0.1f);
tPaint.setTextAlign(Paint.Align.LEFT);
setBackgroundColor(Color.BLACK);
for (k = 0; k < j; k++){
char c = WORD.charAt(k);
String cs = Character.toString(c);
textToPrint+= cs;
textspace =(float) (k*(width/WORD.length())*.9);
canvas.drawTextOnPath(cs, arc, textspace , 0, tPaint);
}
if(j<WORD.length()){
j++;
}
}
}
In my Android app, I am trying to show letters one by one with a short delay between each, while also playing a sound for each letter. I have everything working, and the sounds play with the correct delay, but the text always prints to the screen far too fast. The canvas seems to be updated even when i am not specifically invalidating the view.
Here is what I have so far - I also tried a variant of this based on the "snake" example and had the same results... any help would be appreciated!
public class SpellingView extends View {
private static final String WORD = "TRUCK";
int width;
int height;
String textToPrint;
float textspace;
int j=0;
private final Path arc;
private final Paint tPaint;
//constructor for SpellingView
public SpellingView(Context context) {
super(context);
arc = new Path();
tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
displayLetterLoop();
}
public void displayLetterLoop(){
for (int i = 0; i < WORD.length(); i++){
final Runnable mUpdateUITimerTask = new Runnable() {
public void run() {
Spelling.mp.start();
}
};
final Handler mHandler = new Handler();
mHandler.postDelayed(mUpdateUITimerTask, i*1500);
}
}
@Override
protected void onDraw(Canvas canvas) {
int k;
// Drawing commands go here
width = canvas.getWidth();
height = canvas.getHeight();
arc.addArc(new RectF((width*.15f), (height*.15f), (width*.85f), (height*.4f)), 180,180);
tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
tPaint.setColor(Color.RED);
tPaint.setTextSize(height * 0.1f);
tPaint.setTextAlign(Paint.Align.LEFT);
setBackgroundColor(Color.BLACK);
for (k = 0; k < j; k++){
char c = WORD.charAt(k);
String cs = Character.toString(c);
textToPrint+= cs;
textspace =(float) (k*(width/WORD.length())*.9);
canvas.drawTextOnPath(cs, arc, textspace , 0, tPaint);
}
if(j<WORD.length()){
j++;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当自定义视图是布局的一部分且由于某种原因重绘自身时,自定义视图将自行失效。因此,您可以使用条件和标志将代码封装在 onDraw() 中,以便仅当计时器设置标志并调用 invalidate 时才绘制您的内容。绘制一个字母后,应将标志设置为 false,例如:
但是,这也可能需要是一个同步块。
Custom view will invalidate itself when is a part of a layout which for some reason redraw itself. Therefore you could envelop your code in onDraw() with a condition and a flag so that it draws your stuff only when the timer sets the flag and calls invalidate. After one letter is drawn then the flag shoud be set on false like:
However this also may need to be a sychronized block.
OnDraw 应该每秒发生 60 次,而不仅仅是在您失效时发生。
因此,也许您需要更新一些类变量(当您失效时)并将它们用于您的绘制逻辑@OnDraw。
OnDraw should happen 60 times a second and not only when you are invalidating.
So maybe you need to update some class variables (when you are invalidating) and use those for your draw logic @ OnDraw.