florisboard / florisboard

An open-source keyboard for Android which respects your privacy. Currently in early-beta.
https://florisboard.org
Apache License 2.0
6.05k stars 403 forks source link

Improve Keyboard-Loading-Screen #207

Closed Glitchy-Tozier closed 3 years ago

Glitchy-Tozier commented 3 years ago

Environment information

Steps to reproduce

  1. Unclear
  2. Click on something that opens up the keyboard (For example the browser search-bar)
  3. See the selection-keyboard flash for a split second. Then the proper keyboard opens

I thought I had seen this issue already somewhere, but I couldn't find it, which is why i decided to create a new one.

Also, by "Selection keyboard", I meant this: Screenshot_20210118-211429_GitHub.jpg

patrickgold commented 3 years ago

Thanks for reporting this! This bug is a nasty one, as it seems to randomly appear, then disappear again and I have no clue what it is causing. Normally you should either instantly see the proper keyboard or the "Loading keyboard, please wait..." screen. This "selection keyboard flash" bug was existent for me about two versions ago (v0.3.1) but then disappeared on all my testing devices, so I thought I somehow fixed it. Good to know it is still there :)

I will place this on my todo list for the current milestone to investigate what exactly this is caused by and will try to fix it.

tsiflimagas commented 3 years ago

I think it was there for me too on v0.3.2 but never happened again on v0.3.3. So you probably want to try it.

kj7rrv commented 3 years ago

I still have it occasionally in 0.3.2. Moto G Power 2020, nonrooted stock Android 10.

On Mon, Jan 18, 2021, 13:46 Kostas Giapis notifications@github.com wrote:

I think it was there for me too on v0. 3.2 but never happened again on v0.3.3. So you probably want to try it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/florisboard/florisboard/issues/207#issuecomment-762483878, or unsubscribe https://github.com/notifications/unsubscribe-auth/AN54XPZPJEIP3B67BPJWGTLS2STZRANCNFSM4WHZBXEA .

Glitchy-Tozier commented 3 years ago

Yo guys, I've figured it out! :)

(Or at least I have figured out ONE way of consistently reproducing it)

Every time you rotate the screen, the next time you open the keyboard, it should flash the Selection-Board.

This also happens when you rotate the scree 90° AND THEN ROTATE IT BACK 90°. Meaning that even if you return to your original position without before re-opening the keyboard, It will flash the Selection-Board. (Does this paragraph make sense to you?)

Also, the App doesn't seem to make a difference. I can reproduce this consistently in my launcher, Fennec (Firefox), and Omni Notes.

I assume flash duration depends on how rescource-demanding the app is, but I'm not sure.

I could upload a video for you, but I think it's best for you to test it yourself. (Because it's more fun and to see whether you guys can reproduce this.)

patrickgold commented 3 years ago

Thanks everyone for your observations and feedback!

Every time you rotate the screen, the next time you open the keyboard, it should flash the Selection-Board.

@Glitchy-Tozier I am able to reproduce this now on v0.3.2 (at least on my older physical devices) when rotating the screen. This makes sense as Android rebuilds a keyboard upon orientation change to properly reload the UI. Though I am unable to reproduce this bug in v0.3.3 on any device (old and new, slow and fast).

Also, the App doesn't seem to make a difference. I can reproduce this consistently in my launcher, Fennec (Firefox), and Omni Notes.

This is correct, the target app has nothing to do with this bug.

I assume flash duration depends on how rescource-demanding the app is, but I'm not sure.

It has definitely something to to with high CPU load (which v0.3.3 vastly improved), maybe this is the reason we can't "see" the bug visually anymore because it is just a millisecond long now.

It would be interesting to see if v0.3.3 fixes this bug on your device too when it arrives on your device.

Glitchy-Tozier commented 3 years ago

I feel like it would be a good idea to get to the bottom of this instead of hoping that the issue disappears or gets too small to be noticed.

Anyway, I'll definitely report back when I see the issue in the v0.3.3 release.

kj7rrv commented 3 years ago

Reproduced in 0.3.2, Moto G Power 2020, stock nonrooted Android 10.

On Tue, Jan 19, 2021, 07:05 Glitchy-Tozier notifications@github.com wrote:

I feel like it would be a good idea to get to the bottom of this instead of hoping that the issue disappears or gets too small to be noticed.

Anyway, I'll definitely report back when I see the issue in the v0.3.3 release.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/florisboard/florisboard/issues/207#issuecomment-762900799, or unsubscribe https://github.com/notifications/unsubscribe-auth/AN54XP5KCCV2LGDLRLTSULTS2WNUJANCNFSM4WHZBXEA .

Glitchy-Tozier commented 3 years ago

Okay, I, too, can't reproduce this on v0.3.3.

What now happens though is that this briefly shows up: Screenshot_20210121-142521_VLC.jpg

Is this intended to happen?

patrickgold commented 3 years ago

Yes this is intended to happen, because there's s short amount of time between the Service onCreate() event and the layout actually being loaded and I have to show something while the layout loads. The initial loading time has been vastly improved since v0.1.0 and will over the time continue to improve. My long-term goal is to have at least the main layout load as fast as in Gboard (which is almost instant even on old devices) until v1.0.0.

Glitchy-Tozier commented 3 years ago

Okay that sounds great!

Idea:

  1. Is delaying the keyboard until it has finished loading an option? Or do you immediately need to fill the space somehow?
  2. If the previous point does not work: How about showing a (previously generated picture) of the keyboard? Something like this: florisLoadImage_edited This could be an image that is created by FlorisBoard in advance. When? When the user exits the settings. As you can see, there's very little information displayed,
    • making it clear that this is a loading screen
    • making the picture easy to generate. All you need to know are themes, number of bottom buttons (is there an emoji-button?) and what the top-bar looks like. You could make it even more basic by clearing out even more content.
  3. If the previous point does not work: Center the text?
Glitchy-Tozier commented 3 years ago
  1. making the picture easy to generate. All you need to know are themes, number of bottom buttons (is there an emoji-button?) and what the top-bar looks like. You could make it even more basic by clearing out even more content.

Actually, shift and enter should maybe be cleared as well, as they are different depending on settings (keep shift alive) and context (on the enter-button, there can either be that search button or different kinds of arrows) The top bar could also be made blank (except for the white button i think), just for the purpose of getting the "loading"-message across.

patrickgold commented 3 years ago

That's actually a neat idea (no. 2) which I definitely consider implementing! Though as I soon start my next mega-project (word suggestions), I don't think this topic will be handled before the v0.4.0 release. I will place it on the v0.5.0 milestone!

Glitchy-Tozier commented 3 years ago

It's not that important urgent anyways, just something that's nice to have.

That's actually a neat idea which I definitely consider implementing!

Btw, were you talking about nr. 1 or nr. 2?

patrickgold commented 3 years ago

I was talking about no. 2, sorry for the missing reference

Glitchy-Tozier commented 3 years ago

I see. So nr.1 doesn't work?

Should I create a new issue for that and close this one? Or just rename it? Or do nothing?

patrickgold commented 3 years ago

No. 1 does not quite work as is just feels like that the keyboard does not respond at first. Also I would have to put a purposely delay when giving the Android system feedback what UI Views FlorisBoard uses (and that is not great).

No 2. though provides an instant feedback to the user, indicating FlorisBoard has understood it should wake up and show the keyboard. This empty pen-generated image you suggested together with some loading effect on top indicates that FlorisBoard has noticed the request and prepares everything, while giving the user something to look on.

Should I create a new issue for that and close this one? Or just rename it? Or do nothing?

I'd suggest we use this issue to discuss the topic around the loading process (so both the selection board flash bug as well as the request for a more nice looking loading placeholder). So basically renaming it would be the best.

Glitchy-Tozier commented 3 years ago

No. 2 it is, then!

Hit me up when you start working on it, I'd love to give feedback. :)

(((Also, just because it's fun, here's a better picture.))) florisLoadImage_edited2

kj7rrv commented 3 years ago

Just my suggestion, maybe have all of the buttons blank? IMO it would look better than having a couple of them not blank.

On Thu, Jan 21, 2021, 10:14 Glitchy-Tozier notifications@github.com wrote:

No. 2 it is, then!

Hit me up when you start working on it, I'd love to give feedback. :)

(((Also, just because it's fun, here's a better picture.))) [image: florisLoadImage_edited2] https://user-images.githubusercontent.com/59611881/105393637-dc4ff780-5c1c-11eb-9a5d-8511fbef2aca.png

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/florisboard/florisboard/issues/207#issuecomment-764840770, or unsubscribe https://github.com/notifications/unsubscribe-auth/AN54XPZ3HB6ZDAXCMGAVR5TS3BVJBANCNFSM4WHZBXEA .

Glitchy-Tozier commented 3 years ago

That's an idea. I tried leaving some buttons filled, to make it look less ... boring. Sounds like a nice, consistent idea though. Another reason for the partial layout: It may better convey to the user "we're constructing the keyboard."

I also just thought ... @patrickgold, what happened to that orange button from the FlorisBoard-logo?


Three pictures, the first one @kj7rrv's suggestion: florisLoadImage_edited3 florisLoadImage_edited4 florisLoadImage_edited5

patrickgold commented 3 years ago

Thanks for the suggestions! I know I said I wanted to work on this only after v0.4.0 is released, but I just had an idea how to simply implement it while respecting the theme colors the user may have set. So I added a static LayoutData object (basically the definition of which keys exist where) which is built on compile time and instantly ready for use. So when FlorisBoard loads, it instantly shows this pregenerated keyboard until the character layout is available.

What do you think of this loading effect (the colors are based on the selected theme, in this case Floris Day):

https://user-images.githubusercontent.com/19412843/105402924-4de17300-5c28-11eb-917c-ace1c57e7341.mp4

Note that the long loading time is simulated, normally FlorisBoard is faster in booting up.

I also just thought ... @patrickgold, what happened to that orange button from the FlorisBoard-logo?

Well it should represent the other main color of FlorisBoard. The text color of the shift key uses this color, but on such a small logo I could just fill a button with this color or else you wouldn't even see it.

patrickgold commented 3 years ago

Ok after further experimenting I reduced the pulsating alpha range from 0.2<->1.0 to 0.4<->1.0 and I think it looks a bit better. Also I am using the Smartbar button background instead of the key background theme attribute for borderless themes to achieve a similar loading effect for these themes.

Edit: Demo for loading in night mode:

https://user-images.githubusercontent.com/19412843/105404500-563aad80-5c2a-11eb-98f0-06046dd53b14.mp4

Glitchy-Tozier commented 3 years ago

It looks really nice! I have to be honest though, I also see two problems:

  1. (It may be a lot of work for a small payoff as the pulsing may not even be properly seen by users)
  2. The problem with pulsating may be that switching to the real keyboard mid-pulse (let's say 0.7) may look worse than when just going from 1.0 to keyboard

I would immediately go for it if it wasn't for this second point.

patrickgold commented 3 years ago

Thanks for your feedback!

(It may be a lot of work for a small payoff as the pulsing may not even be properly seen by users)

That's what I thought too, but it is actually this piece of code which does the animation:

animator = ObjectAnimator.ofFloat(this, "alpha", 0.4f, 1.0f).apply {
    duration = 650
    repeatCount = ValueAnimator.INFINITE
    repeatMode = ValueAnimator.REVERSE
    start()
}

So not at all that difficult or much work :)

The problem with pulsating may be that switching to the real keyboard mid-pulse (let's say 0.7) may look worse than when just going from 1.0 to keyboard

Ok that's a valid point but to be honest it does not look that bad on my OnePlus 7T (it is noticable that there's some preview but it is gone very fast). I could also just let it static but for older/slower devices this looks cooler. Aaargh, that's now a difficult decision.

Glitchy-Tozier commented 3 years ago

Maybe it looks less sudden of a change when starting with a low number. This may lower the odds of the keyboard spawning while while the load-animation is fading away.

Could you maybe show this approach with something short, like a 0,5sec or 0,2sec loading-time? It would also be interesting to see how the static loading-picture looks in that situation

((I'll reply to everything else in like 11 hours))

patrickgold commented 3 years ago

Maybe it looks less sudden of a change when starting with a low number.

That would be an approach which is feasible yeah, will try it out.

Could you maybe show this approach with something short, like a 0,5sec or 0,2sec loading-time?

https://user-images.githubusercontent.com/19412843/105405841-e7f6ea80-5c2b-11eb-981b-4bdc49a9786b.mp4

It would also be interesting to see how the static loading-picture looks in that situation

https://user-images.githubusercontent.com/19412843/105405986-17a5f280-5c2c-11eb-9415-52408e0f8f96.mp4

Glitchy-Tozier commented 3 years ago

You're right, the first one really is flashier. If it didn't fade away and THEN disappear, it might look even better...

patrickgold commented 3 years ago

Well it is difficult for me to predict how long FlorisBoard will load - so I might do what you said: start with a low alpha number, then do the animation. So the odds of a flash are lower (of course not zero)

patrickgold commented 3 years ago

Ok I may have some ideas but as you are probably off now, I will continue discussing and improving this feature tomorrow together with you. Meaning it will not make it into v0.3.4, but it is more important for me that I implement this right :)

Glitchy-Tozier commented 3 years ago

Hi again!

Ok I may have some ideas What are the ideas?

I feel like there are two criteria for the loading-screen here

  1. [more important] It needs to look good with a very short loading-time (which should be what happens on most devices)
  2. [less important] It would be nice if it conveyed a "loading"-message to users on very slow devices
Glitchy-Tozier commented 3 years ago

With those criteria in mind, here are two ideas that bothered me during the night. So let me share them with you. They're slightly more complex though.


1. Incremental increase

florisLoadImage_edited6 Basically, what I did is:

No idea what this actually looks like on the keyboard.

You could even make those rows fade-in (starting from what you can see in the picture. This could be nicer than the regular fade-ins we discussed before as it could take longer (as the top row has a higher opacity).

Implementation: Create a picture like this one ⬆️⬆️⬆️, then gradually fade in another blank keyboard, starting with 100% opacity.


2. Blank keyboard, Loading circle.

florisLoadImage_edited7 (obviously animate the loading-circle.)

It's probably less flashy on very slow devices though.


If you think those ideas are viable, could you try them out and share the result?

patrickgold commented 3 years ago

What are the ideas?

  1. idea: currently the animation is like this: 1.0 -fade-> 0.4 -fade-> 1.0 (infinite loop as long as loading). Lets say the loop is currently at 0.7 and suddenly the character layout is available, then this happens: 0.7 -cancel_and_reset-> 1.0. I could do this instead: 0.7 -cancel_but_stay-> 0.7 -one_time_fade-> 1.0. This would give the pulse a more natural ending, regardless where the current fade animation was.
  2. I could do something in the direction of a shimmer effect. This effect was born by Facebook but is used in many apps nowadays and means that content is loading. I would somewhat replicate this effect, but less flashy , maybe this looks better. If I end up doing something in that direction I will still write the animation myself, as I do not want to add a Facebook library to FlorisBoard, open-source or not.
  3. Make the period time of the animation faster and allow the character layout only to introduce itself if the animation is >0.8, else wait until it has reached this value or higher again. This of course would add a slight delay (0ms to 650ms in the absolute worst case) but the animation does not seem to be cut off.
patrickgold commented 3 years ago

[more important] It needs to look good with a very short loading-time (which should be what happens on most devices)

This is true, that's why I am trying out so many approaches here

[less important] It would be nice if it conveyed a "loading"-message to users on very slow devices

The alpha fade or shimmer effect is the "loading" message, as this is used by many apps nowadays to tell the user "Hey, I'm still loading, please wait"

patrickgold commented 3 years ago
  1. Incremental increase

So you mean I should gradually fade the opacity in from the bottom or are the opacity values static for each row and stay as long as the keyboard loads? Doesn't this still create a flash, as the opacity changes drastically as soon as the character keyboard has loaded?

  1. Blank keyboard, Loading circle.

The problem with this is that the Smartbar is not properly initialized until the character layout has loaded, so I cannot work with UI elements in the Smartbar.

Glitchy-Tozier commented 3 years ago

Replies to your ideas

  1. idea: currently the animation is like this: 1.0 -fade-> 0.4 -fade-> 1.0 (infinite loop as long as loading). Lets say the loop is currently at 0.7 and suddenly the character layout is available, then this happens: 0.7 -cancel_and_reset-> 1.0. I could do this instead: 0.7 -cancel_but_stay-> 0.7 -one_time_fade-> 1.0. This would give the pulse a more natural ending, regardless where the current fade animation was.

Could you elaborate? I don't understand.

  1. I could do something in the direction of a shimmer effect.

I feel like that could have the same problem as my 1. Incremental increase-idea.

  1. Make the period time of the animation faster and allow the character layout only to introduce itself if the animation is >0.8, else wait until it has reached this value or higher again.

This probably is the prettiest one of all of them, but I really think we shouldn't slow down the keyboard on purpose. So this is the variant i would only pick if nothing else works.

Replies to your replies to my ideas

  1. Incremental increase

So you mean I should gradually fade the opacity in from the bottom or are the opacity values static for each row and stay as long as the keyboard loads?

I meant

  1. start with the picture I posted and use it as a background
  2. insert your flashing-animation, but go from 0,0 to 1,0 and then stop. Make this fade-in slower than the previous animations though; let it take something like 1 second.

Doesn't this still create a flash, as the opacity changes drastically as soon as the character keyboard has loaded?

This definitely could be a problem. I was hoping that those "steps" could make it feel a little less jarring, even if the keyboard quickly pops up. It's hard to judge for me though, without seeing anything. (i tried switching between images, but that doesn't quite do the trick.)

The problem with this is that the Smartbar is not properly initialized until the character layout has loaded, so I cannot work with UI elements in the Smartbar.

But that one, circular button at the top right will always exist, regardless of the settings and regardless of what smart-bar is being used, right? If this is the case, I don't understand what the problem is.

patrickgold commented 3 years ago

Replies to your replies to my ideas

  1. This is what I meant: image The solid fat blue line is the graph of the current opacity value of the keyboard. As you can see, at the exact moment the character keyboard is loaded, the opacity jumps back to 1.0. I want to avoid this instant jump by gradually going up to 1.0 (the dotted orange line, meaning the character layout will start with the current opacity value and go up to 1.0). This should make the loading ending more natural, as it is not an instant jump.

  2. Yeah I know and it is the most difficult, so I think I will void this idea.

  3. I also agree that we should use this only as an absolute fallback if nothing else works.

Replies to your replies to my replies to your idea

I meant start with the picture I posted and use it as a background insert your flashing-animation, but go from 0,0 to 1,0 and then stop. Make this fade-in slower than the previous animations though; let it take something like 1 second.

I do not even need a picture for this, as the precompiled placeholder keyboard you can see on my above screen recordings is already instantly available and it is easier to work with. I can definitely try this, but I think this has the same flash effect as if all rows have the same opacity.

This definitely could be a problem. I was hoping that those "steps" could make it feel a little less jarring, even if the keyboard quickly pops up. It's hard to judge for me though, without seeing anything. (i tried switching between images, but that doesn't quite do the trick.)

I think if we combine my idea 1 with your above idea it could work out somehow. Will definitely have to experiment though with this.

But that one, circular button at the top right will always exist, regardless of the settings and regardless of what smart-bar is being used, right? If this is the case, I don't understand what the problem is.

I would have to insert a rotating loading icon button and tweak the Smartbar feature visibility method to allow for this to happen, as currently during loading the Smartbar is missing the context information regarding which keyboard is loaded (and the placeholder keyboard is not seen as a "real" keyboard by the Smartbar). Still, personally I would like to achieve a loading effect using only the precompiled keyboard.

Glitchy-Tozier commented 3 years ago

Replies to your replies to my replies to your ideas.

  1. This is what I meant: [picture]

Really nice drawing, is that draw.io?

I like that idea. Two important things: (I'm guessing that's what you had in mind anyway.)

  1. the user must be able to input things as soon as possible
  2. the user has to know that he can input things as soon as the keyboard is ready (probably automatically achieved by the letters spawning. Also, I'm thinking, maybe, the letters should instantly be shown, no fading, to increase this effect.)

Additionally, the final fade-in could be sped up. Here, a drawing of my own :) Untitled Diagram (blue is the placeholder image, red is the actual keyboard)

Replies to your replies to my replies to your replies to my idea

(^this starts getting a little too much for my head…)

I was hoping that those "steps" could make it feel a little less jarring, even if the keyboard quickly pops up. It's hard to judge for me though, without seeing anything. (i tried switching between images, but that doesn't quite do the trick.)

I think if we combine my idea 1 with your above idea it could work out somehow. Will definitely have to experiment though with this.

Sounds good! I feel like it is going to be either the full-keyboard pulse or that incremental-keyboard-pulse.

Still, personally I would like to achieve a loading effect using only the precompiled keyboard.

Combining

  1. this preference ⬆️⬆️ of yours and
  2. the fact that your first idea seems really good,

... I think we can forget about the loading-circle.

patrickgold commented 3 years ago

Ok the headings now also start to be a little much for my head, so I will just sum up everything in here :)

Really nice drawing, is that draw.io?

Yup :)

I like that idea. Two important things: (I'm guessing that's what you had in mind anyway.) the user must be able to input things as soon as possible the user has to know that he can input things as soon as the keyboard is ready (probably automatically achieved by the letters spawning. Also, I'm thinking, maybe, the letters should instantly be shown, no fading, to increase this effect.)

Yes, the keyboard is instantly fully usable from the moment the character keyboard is loaded. The only thing is that for a few hundred ms the background of the keys is not 100% opacity, but with the sped up idea I do think that it is very clear that the keyboard is fully usable.

Additionally, the final fade-in could be sped up. Here, a drawing of my own :)

That's actually a good idea I haven't thought of. Also nice drawing, helps in visualizing the speed up :)

I feel like it is going to be either the full-keyboard pulse or that incremental-keyboard-pulse.

Jup. I will now boot up Android Studio and start experimenting. I will share quite a few screen recordings then so we can see which one actually looks the best.

patrickgold commented 3 years ago

Ok this took longer than expected but I finally have some results to show.

First off, I was adding some delay to text out the animation. While doing this, I rotated the screen and what greeted me - the selection keyboard! I went on full investigation now that I was finally able to reproduce this ugly bug and after finding out what was going wrong, this is now fixed. Without going in too technical, I somehow ignored that indexOfChild() returns -1 instead of null, which got converted to 1. This number was the index of the selection keyboard and this was also the reason why we saw this instead of the loading keyboard. But like I said, this is now finally eliminated. :)

This video below contains 6 different screen recordings of different things I tried out. The animation properties are as follows:

    duration = 500ms
    startAlpha = 1.0 (starting with 100% because else the animation is super ugly for fast devices)
    endAlpha = 0.4
    repeats = infinte until stopped

The first 3 are without a fade for the character layout, the other 3 with (the effect we drew with our diagrams). The character one-time-fade's length is 0-250ms, depending on the current alpha value. I have added three stages of on-purpose loading-delays to showcase how it looks in such case.

Sorry for the delays in between, this was me applying the effects

https://user-images.githubusercontent.com/19412843/105528965-f0136080-5ce5-11eb-8cda-634e5c5d2486.mp4

patrickgold commented 3 years ago

Ok now I've tried out pulsating + one-time-fade to 100% + your faded row idea and this looks even better imo, I am really amazed:

https://user-images.githubusercontent.com/19412843/105529745-1d144300-5ce7-11eb-844c-2570c2f8e0e2.mp4

EDIT: This is what it looks like with an on-purpose 500ms loading delay + how it looks when the screen is rotated:

https://user-images.githubusercontent.com/19412843/105530711-6d3fd500-5ce8-11eb-807f-fa68d8553492.mp4

EDIT2: With no on-purpose delay, the first time loading is almost instant and looks pretty good on a fast device and when rotating the screen the character layout is as fast as fast as the loading keyboard.

Glitchy-Tozier commented 3 years ago

This number was the index of the selection keyboard and this was also the reason why we saw this instead of the loading keyboard. But like I said, this is now finally eliminated. :)

Yay, finally we know what it was! Do you have any idea why it disappeared temporarily?

[video] (mid-writing, they turned into 3 videos)

I have to say, they all look really nice, great job! I couldn't decide between one of them. Though the staggered screen-saver (last videos) does look pretty sweet.

I have two annoying requests:

  1. What I originally meant was that, in the faded-rows-idea, the real keyboard doesn't have the same opacity everywhere, when doing the last fade-in. It should have the same faded rows as the rest of the animation, which gradually turn opaque. (Does that request make sense?)
  2. What does it look like when making the letters opaque immediately?
EDIT:

Third request: Could you try this? (Or...what do you think about this?):

Glitchy-Tozier commented 3 years ago

Requests 1&2 are more important than 3 though.

Edit 1: ((Either way, the transitions look amazing as of now)) Edit 2: Again, off for now, I'll reply in about 12h.

patrickgold commented 3 years ago

Yay, finally we know what it was! Do you have any idea why it disappeared temporarily?

I am not 100% sure but may have something to do with the fact that in some cases indexOfChild() got a null reference (where the bug then didn't appear) and sometimes a reference to a non-attached View (in this case -1 was returned and the bug appeared).

What I originally meant was that, in the faded-rows-idea, the real keyboard doesn't have the same opacity everywhere, when doing the last fade-in. It should have the same faded rows as the rest of the animation, which gradually turn opaque. (Does that request make sense?)

Ah I see what you mean now, will try this out.

What does it look like when making the letters opaque immediately?

I cannot make the text 100% while having the background at some X% opacity. This is technically very difficult and would require me to completely rewrite the Key draw code, which I don't want to do as this is too much work for this feature.

Third request: Could you try this? (Or...what do you think about this?): Fade in the faded-rows only once, going from X.0 to 1.0 and then stopping. This means that on very very slow devices, it would just do nothing, once it's over.

Like I said I prefer to begin with 1.0 opacity as else fast devices are forced to always fade in, regardless how fast the layout loads. See the following two screen recordings (both have no added delay, only the animation and the time it takes to load on an OnePlus 7T):

0.4 to 1.0

https://user-images.githubusercontent.com/19412843/105539209-c3b31080-5cf4-11eb-951a-b63d1d6108e8.mp4

1.0 to 0.4

https://user-images.githubusercontent.com/19412843/105539240-cb72b500-5cf4-11eb-9a5f-783334e5f4c5.mp4

Glitchy-Tozier commented 3 years ago

Ah I see what you mean now, will try this out.

Great!

I cannot make the text 100% while having the background at some X% opacity.

I see, that's fine then.

Like I said I prefer to begin with 1.0 opacity as else fast devices are forced to always fade in, regardless how fast the layout loads.

Okay, I see what you mean. I'm thinking it might look even slightly better when starting with sth like 0,9 or 0,95 opacity. I just don't like the thought of a short opacity fall, followed by an short rise. That means it'll always flicker.

So als a last resort, I'd be interested in something like opacity 0,9 → 1,0 → 0,4 → 1,0 → 0,4 → ... If you don't want try do this, I agree; 1,0 → 0,4 looks better

That's just me nitpicking though. I might think I see that flicker because the faded-rows-fade-in isn't implemented yet, meaning that the top rows immediately get a big opacity-boost.

patrickgold commented 3 years ago

Ok so I've tried quite a few different variations and came to this conclusion:

Even though the faded-row idea looks prettier on mid-range to slow devices, on fast devices you have the problem that the top row has to go up by 75%p, regardless how hast it loads (so the same problem as starting with 0.4). So after quite a long time of fine-tuning, I finally want to complete this topic and work on resolving some other issues which arose in the meantime.

This is the final result of the loading effect: 0.9 → 1.0 → 0.4 → 1.0→ 0.4 → ... Each alpha cycle has a duration of exactly 500 ms When the keyboard has fully loaded, the infinite cycle is canceled and a one-time fade to 1.0 is started. This opacity fade is dependent on the current alpha value, but is always in the range 0ms to 125ms to make the transition to fully opaque faster.

Screen recording on my OnePlus 7T (fast device)

https://user-images.githubusercontent.com/19412843/105579037-38815b80-5d84-11eb-9a93-eb0dc881e3d5.mp4

Screen recording on my old Huawei P9 lite

The screen recorder isn't the best though, IRL the pulse feels more fluent.

https://user-images.githubusercontent.com/19412843/105579039-3c14e280-5d84-11eb-8e84-e4c814b649ea.mp4

Note: I am off for the next ~3 hours so I will not be able to respond to you immediately.

Glitchy-Tozier commented 3 years ago

Okay, looks great! Lets go for your final decision then! :)

Also, I just realized, this might get annoying with app-dependent themes... Depending on how you implemented them.

patrickgold commented 3 years ago

Okay, looks great! Lets go for your final decision then! :)

👍

Also, I just realized, this might get annoying with app-dependent themes... Depending on how you implemented them.

Just checked this one out and it works like a charm, it automatically adapts before the first frame is drawn.

Glitchy-Tozier commented 3 years ago

Just checked this one out and it works like a charm, it automatically adapts before the first frame is drawn.

Amazing! And you managed to create all those animations without adding much extra loading-time?

patrickgold commented 3 years ago

And you managed to create all those animations without adding much extra loading-time?

I think it added maybe 3-5ms additional loading time on initial startup, but that is unavoidable, as I have to assign the animation object and start it. Though ObjectAnimator is very optimized and then runs fluently in the background. When rotating the screen it added max <1ms, as the layout is already cached and it loads very quickly, even on my old Huawei P9 lite.

The good thing is while fine-tuning was a lot of work, the actual end result of code lines which do the animation are very small and it is very easy to do fine-tuning in the future if necessary.

Glitchy-Tozier commented 3 years ago

Ok, yeah, 3-5ms is pretty much nothing

Also, nice, it's always fun if verly little code does a lot of work for you! :)