├── .gitignore ├── preview ├── normal_case.gif ├── normal_case.mp4 ├── blank_cold_start.gif ├── blank_cold_start.mp4 ├── material_cold_start.gif └── material_cold_start.mp4 ├── raw-sw600dp ├── window_background_statusbar_toolbar_tab.9.shsvg └── window_background_statusbar_toolbar_tab.9.shsvg.conf ├── raw-v23 ├── window_background_statusbar_toolbar_tab.9.shsvg └── window_background_statusbar_toolbar_tab.9.shsvg.conf ├── raw-sw600dp-v23 ├── window_background_statusbar_toolbar_tab.9.shsvg └── window_background_statusbar_toolbar_tab.9.shsvg.conf ├── raw ├── window_background_statusbar_toolbar_tab.9.shsvg.conf └── window_background_statusbar_toolbar_tab.9.shsvg ├── .gitmodules ├── colors.conf ├── gen-png.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | gen/ 2 | -------------------------------------------------------------------------------- /preview/normal_case.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanghai/MaterialColdStart/HEAD/preview/normal_case.gif -------------------------------------------------------------------------------- /preview/normal_case.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanghai/MaterialColdStart/HEAD/preview/normal_case.mp4 -------------------------------------------------------------------------------- /raw-sw600dp/window_background_statusbar_toolbar_tab.9.shsvg: -------------------------------------------------------------------------------- 1 | ../raw/window_background_statusbar_toolbar_tab.9.shsvg -------------------------------------------------------------------------------- /raw-v23/window_background_statusbar_toolbar_tab.9.shsvg: -------------------------------------------------------------------------------- 1 | ../raw/window_background_statusbar_toolbar_tab.9.shsvg -------------------------------------------------------------------------------- /preview/blank_cold_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanghai/MaterialColdStart/HEAD/preview/blank_cold_start.gif -------------------------------------------------------------------------------- /preview/blank_cold_start.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanghai/MaterialColdStart/HEAD/preview/blank_cold_start.mp4 -------------------------------------------------------------------------------- /raw-sw600dp-v23/window_background_statusbar_toolbar_tab.9.shsvg: -------------------------------------------------------------------------------- 1 | ../raw/window_background_statusbar_toolbar_tab.9.shsvg -------------------------------------------------------------------------------- /preview/material_cold_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanghai/MaterialColdStart/HEAD/preview/material_cold_start.gif -------------------------------------------------------------------------------- /preview/material_cold_start.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanghai/MaterialColdStart/HEAD/preview/material_cold_start.mp4 -------------------------------------------------------------------------------- /raw-v23/window_background_statusbar_toolbar_tab.9.shsvg.conf: -------------------------------------------------------------------------------- 1 | source "$(dirname "${BASH_SOURCE[0]}")/../colors.conf" 2 | 3 | STATUS_BAR_HEIGHT=24 4 | APPBAR_HEIGHT=104 5 | APPBAR_SHADOW_HEIGHT=4 6 | -------------------------------------------------------------------------------- /raw/window_background_statusbar_toolbar_tab.9.shsvg.conf: -------------------------------------------------------------------------------- 1 | source "$(dirname "${BASH_SOURCE[0]}")/../colors.conf" 2 | 3 | STATUS_BAR_HEIGHT=25 4 | APPBAR_HEIGHT=104 5 | APPBAR_SHADOW_HEIGHT=4 6 | -------------------------------------------------------------------------------- /raw-sw600dp/window_background_statusbar_toolbar_tab.9.shsvg.conf: -------------------------------------------------------------------------------- 1 | source "$(dirname "${BASH_SOURCE[0]}")/../colors.conf" 2 | 3 | STATUS_BAR_HEIGHT=25 4 | APPBAR_HEIGHT=112 5 | APPBAR_SHADOW_HEIGHT=4 6 | -------------------------------------------------------------------------------- /raw-sw600dp-v23/window_background_statusbar_toolbar_tab.9.shsvg.conf: -------------------------------------------------------------------------------- 1 | source "$(dirname "${BASH_SOURCE[0]}")/../colors.conf" 2 | 3 | STATUS_BAR_HEIGHT=24 4 | APPBAR_HEIGHT=112 5 | APPBAR_SHADOW_HEIGHT=4 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "scripts"] 2 | path = scripts 3 | url = git@github.com:zhanghai/AndroidSVGScripts.git 4 | [submodule "shsvg"] 5 | path = shsvg 6 | url = git@github.com:zhanghai/AndroidSVGScripts.git 7 | -------------------------------------------------------------------------------- /colors.conf: -------------------------------------------------------------------------------- 1 | COLOR_PRIMARY_DARK=#388e3c 2 | COLOR_PRIMARY=#4caf50 3 | COLOR_WINDOW_BACKGROUND=#eeeeee 4 | COLOR_SHADOW_START=#000000 5 | COLOR_SHADOW_START_OPACITY=0.215686275 6 | COLOR_SHADOW_END=#000000 7 | COLOR_SHADOW_END_OPACITY=0.011764706 8 | -------------------------------------------------------------------------------- /gen-png.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir -p gen 3 | cd gen 4 | ../shsvg/shsvgdpi.sh ../raw/window_background_statusbar_toolbar_tab.9.shsvg 5 | ../shsvg/shsvgdpi.sh ../raw-v23/window_background_statusbar_toolbar_tab.9.shsvg '' '-v23' 6 | ../shsvg/shsvgdpi.sh ../raw-sw600dp/window_background_statusbar_toolbar_tab.9.shsvg '-sw600dp' 7 | ../shsvg/shsvgdpi.sh ../raw-sw600dp-v23/window_background_statusbar_toolbar_tab.9.shsvg '-sw600dp' '-v23' 8 | -------------------------------------------------------------------------------- /raw/window_background_statusbar_toolbar_tab.9.shsvg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MaterialColdStart 2 | 3 | Utilize the window background during cold start time (the time between user launches your app and `Activity.onCreate()` is called) to make your app look faster. 4 | 5 | This project comes with some templates for Material Designed apps, but you can also roll your own if you wish. 6 | 7 | ## Preview 8 | 9 | Blank cold start (Glitch on status bar and appbar) v.s. Material cold start (Preserves visual consistency): 10 | 11 | ![Blank cold start](preview/blank_cold_start.gif) 12 | ![Material cold start](preview/material_cold_start.gif) 13 | 14 | (I deliberately picked a slower device to show the effect clearer, but this improvement is also delightful on faster devices.) 15 | 16 | When your app process is cached in memory but main activity is relaunched, this technique gives the illusion of a much quicker start up. 17 | 18 | ![Normal case](preview/normal_case.gif) 19 | 20 | Notice the small period of time when appbar and status bar is "drawn" but no text is shown — **this is the trick**. 21 | 22 | Without the help of our cold start window background, users will see a glitch of whiteness over the appbar and statusbar. 23 | 24 | ## Inspiration 25 | 26 | This project was inspired by the pro-tip [Use cold start time effectively with a branded launch theme — Pro-tip by +Ian Lake](https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd). 27 | 28 | But instead of using a short transient product logo as preview, I want to use a background with an `AppBar` on it, just like the old days with framework-managed `ActionBar`, which gives user the illusion of a quicker start up and ensures visual consistency. 29 | 30 | This project has been around in my mind for several months, until I found my way to generate drawables with templates. 31 | 32 | ## Implementation 33 | 34 | This project generates nine-patch drawables for use as `android:windowBackground`. 35 | 36 | ### Why nine-patch? 37 | 38 | Only static drawables can be loaded by framework as preview, and all other drawables will only retain aspect ratio when width/height is set. So we need to use nine-patch. 39 | 40 | ### How to generate nine-patch? 41 | 42 | However, nine-patches need to be bitmaps, but we have various dimension sizes changing with configuration, and we still have to retain the one-pixel border while scaling up the content area. 43 | 44 | I don't want to keep a separate file for each combination of configuration (which can be 20 if you support tablet), but instead use a single template for nine-patch generation. After a lot of (painful) trial-and-error with `XSLT` and `sed`, I suddenly found the good old `bash` (which is string-oriented) a viable solution for this problem. 45 | 46 | The solution, a "new" format called `shsvg` (Shell SVG), is implemented as in [zhanghai/AndroidSVGScripts](https://github.com/zhanghai/AndroidSVGScripts) and used by this project. 47 | 48 | ## Usage 49 | 50 | > Note: To generate your own image assets, you will probably need a Linux installation. I may upload some pre-built assets later. 51 | 52 | 1. (Optional) Adjust the appbar height (and more if you want). The default configuration assumes that your app have a `TabLayout`. If however your app does not, you need to modify each `window_background_statusbar_toolbar_tab.9.shsvg.conf` file in the given raw directories and change the `APPBAR_HEIGHT` from `112` to `64` and `104` to `56`. 53 | 54 | 2. Run `gen-png.sh` and copy the output in `gen/` to your `res` directory. (requires `bash`, `bc`, `gcalccmd` (from `gnome-calculator`) and `inkscape`) 55 | 56 | 3. Make a new theme for your main activity: 57 | 58 | ```xml 59 | 62 | ``` 63 | 64 | 4. And set the new theme in your `AndroidManifest.xml`: 65 | 66 | ```xml 67 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | ``` 77 | 78 | 5. Finally in your `MainActivity.java`, set the theme back for the normal window background, which will be transitioned into: 79 | 80 | ```java 81 | public class MainActivity extends AppCompatActivity { 82 | 83 | @Override 84 | protected void onCreate(Bundle savedInstanceState) { 85 | 86 | // Make sure this line comes before calling super.onCreate(). 87 | setTheme(R.style.AppTheme); 88 | 89 | super.onCreate(savedInstanceState); 90 | } 91 | } 92 | ``` 93 | 94 | 6. Enjoy the updated cold start experience! 95 | 96 | ## Pre-built assets 97 | 98 | // TODO 99 | 100 | ## License 101 | 102 | ``` 103 | Copyright 2015 Zhang Hai 104 | 105 | Licensed under the Apache License, Version 2.0 (the "License"); 106 | you may not use this file except in compliance with the License. 107 | You may obtain a copy of the License at 108 | 109 | http://www.apache.org/licenses/LICENSE-2.0 110 | 111 | Unless required by applicable law or agreed to in writing, software 112 | distributed under the License is distributed on an "AS IS" BASIS, 113 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 114 | See the License for the specific language governing permissions and 115 | limitations under the License. 116 | ``` 117 | --------------------------------------------------------------------------------