0

I'm currently working on a random-lightning-generator class in my app. Lightning (extends View) is a random blue path that reveals in a phase and when it's revealed it fades out. I want the lightning to regenerate and show on the canvas again (for now just once, I will later control its repeat-frequency). The lightning-objects class builds its path and draw it on the canvas once. Right now I succeed creating a new lightning using the invalidate() method (to call the onDraw() method), but the lightning won't show on the canvas.

What can I do in order for the regenerated ones to show up? Thank you in advance (:

Nitzan Daloomy
  • 166
  • 5
  • 24
  • In other words, you have called `invalidate()`, but that is not being followed by an `onDraw()`? – greeble31 Jan 08 '20 at 22:53
  • @greeble31 nope... the `onDraw()` starts, but the lightning wont show on the canvas... it is generated behind the scenes, but not coming to stage... I've checked it with log – Nitzan Daloomy Jan 08 '20 at 23:18
  • 1
    If an `onDraw()` follows the `invalidate()`, then the framework is has done its part. The lightning is not showing because you have not drawn it. I am downvoting this question because it does not include any meaningful information concerning how the lightning is drawn. If you edit your question to include the code you are using, what `Canvas` calls you are making, etc., I will remove the downvote. – greeble31 Jan 08 '20 at 23:26
  • @greeble31 ok then, I'll edit it (: – Nitzan Daloomy Jan 09 '20 at 16:17
  • You've got quite a bit of code here; a fairly complicated state machine and a number of advanced animation techniques. Am I to understand that you wrote this entire thing, then went to test it for the first time, and discovered that only the first frame would render? Was there no incremental testing process? – greeble31 Jan 09 '20 at 18:58
  • @greeble31 your assumption is wrong, I've actually tested the code step by step... each segment has functioned well (I've never succeeded with making the lightning appear multiple times though)... – Nitzan Daloomy Jan 09 '20 at 21:34

1 Answers1

1

OK, here is what is going on:

EDIT

As a reminder: The root problem here is that the View's alpha is getting stuck at 0, which means that all drawing operations are hidden, once the first lightning fades out.

In my first revision, I wasn't as specific as I should have been. I just wanted you to change this line:

final ObjectAnimator alpha = ObjectAnimator.ofFloat(RandomLightning.this, "alpha", 0);

to this:

final ObjectAnimator alpha = ObjectAnimator.ofFloat(RandomLightning.this, "alpha", 1.0f, 0);

That, combined with the init2() fix (more on that later), is enough to get things re-drawing at regular intervals. But later, I realized it had a bug: after the 1st lightning, the "phase" animation would stop showing up.

So, don't fix it that way. Instead, just add a call to the top of animateLightning():

setAlpha( 1.0f );

This causes the alpha to reset to 1 at the start of each new lightning, thus putting the state machine back in the original starting state.

Do not add a new ObjectAnimator to the Runnable; it doesn't do anything useful.

ABOUT init2():

I'm not sure why you think the init2() in the Runnable is unnecessary or redundant. You seem to have a misunderstanding about the control flow, but I can't put my finger on what it is.

init2() regenerates your lightning, and restarts the animation state machine. If it is not called in the Runnable, nothing else will call it (you should be able to confirm this using the log), and that means no new lightning, and no animation. (If you disagree, please feel free to comment.)

It should be clear to you that the first lightning only happens because you call init1()/init2() in all the constructors. The second, and all later lightnings, only happen because that Runnable starts executing 5 seconds after the View is created.

greeble31
  • 4,894
  • 2
  • 16
  • 30
  • A. it didn't work, maybe I've used the onFloat() override in the wrong place? anyway, also I've checked it, and when I'm not using the alpha animation, the lightning stays on the screen and the regenerated one won't show either... does't it mean it's not related to the alpha? I really am not sure about it :/ B. I still do appreciate how this question might have been difficult to answer without the code listing. thank you for the effort (: – Nitzan Daloomy Jan 10 '20 at 01:09
  • I'm thinking of asking you to re-post your code, but before you do that, it sounds to me like you might not've added the `init2()` quite the way I intended. You must ensure that `animateLightning()` is being invoked during the course of the `Runnable`; have you verified that it is? – greeble31 Jan 10 '20 at 02:06
  • @IronMan It probably also wouldn't hurt to call `path.reset();` as the first line of `init2()`; this seems to produce more consistent lightning. – greeble31 Jan 10 '20 at 02:17
  • I hope I have added the init2() the way you intended, I've called it in the `Runnable`, right after I call `init1()`... It only makes the lightning regenerate twice every time instead of regenerating twice... also added `path.reset()` as the first line of `init2()`, didn't help :/ with the changes you suggested (hoping I've correctly implemented them) the lightning still doesn't show again. – Nitzan Daloomy Jan 11 '20 at 15:23
  • Well, I mean, when I make those same changes, it works for me, so... please update your question to include the exact code you are using, and I will compare. Also, you lost me with this: "It only makes the lightning regenerate twice every time instead of regenerating twice", that doesn't make sense to me. – greeble31 Jan 11 '20 at 15:56
  • oh, sorry, I wasn't focused... I meant "it only makes the lightning regenerating twice every time instead of regenerating once"... I'll update the question (: thank you! – Nitzan Daloomy Jan 11 '20 at 18:57
  • You're the best! Thank you so much!! first, it works flawlessly! and I did not mean the `init2()` is redundant or unnecessary, I only said that when I call it, 2 lightning are regenerated instead of one only, I see it in the log... (if you have my exact code, you could see an error log shows every time a lightning is generated, and when I use `init2()` two logs appear the same time, instead of just one...). Can you please help me find its cause? – Nitzan Daloomy Jan 11 '20 at 21:37
  • @IronMan you're welcome, but you don't need me to help find the cause... just put a breakpoint on the `Log.d()` call and run the debugger. – greeble31 Jan 11 '20 at 21:45