Road Runner is a library for android which allow you to make your own loading animation using a SVG image

Overview

Road Runner

Download Hex.pm Platform Android Arsenal

Drawing


Road Runner is a library for android which allow you to make your own loading animation using a SVG image

Sample video

View in Youtube

Demo Application

Get on google play #### Road Runner intro

Drawing

Determiante

Drawing

Drawing

Determiante with value update

Drawing

Material animation with twitter logo

Drawing

TwoWay animation with Github logo

Drawing

How to

The library use the standard String path information (only one path) and the original size to works, you need to obtain it using a external tool, the path information look like this:

M306.314,58.9801 C275.235,27.9011,224.837,27.9011,193.759,58.9801
L39.0019,213.736 C15.6832,237.055,15.6832,274.838,39.0019,298.158
C58.2219,317.378,87.2116,320.482,109.874,308.007
C112.241,307.888,114.569,306.993,116.38,305.202 L271.136,150.445
C286.675,134.906,286.675,109.717,271.136,94.1779
C255.597,78.6389,230.408,78.6389,214.869,94.1779 L88.2461,220.8
C84.366,224.68,84.366,230.987,88.2461,234.866
C92.1263,238.746,98.4335,238.746,102.313,234.866 L228.935,108.245
C236.715,100.465,249.309,100.465,257.07,108.245
C264.85,116.025,264.85,128.619,257.07,136.379 L109.337,284.111
C93.7979,299.65,68.6085,299.65,53.0694,284.111
C37.5304,268.572,37.5304,243.383,53.0694,227.844 L207.825,73.0468
C231.144,49.7281,268.928,49.7281,292.247,73.0468
C315.566,96.3654,315.566,134.149,292.247,157.469 L151.558,298.158
C147.678,302.038,147.678,308.345,151.558,312.225
C155.438,316.105,161.745,316.105,165.625,312.225 L306.314,171.535
C337.393,140.457,337.393,90.0591,306.314,58.98 Z

And the width and height can be found in the svg definition:

height="316"
width="512"

Using the view (Samples)

Two way

<com.github.glomadrian.roadrunner.IndeterminateRoadRunner
      android:id="@+id/two_way"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      lib:movement_loop_time="4000"
      lib:movement_direction="counter_clockwise"
      lib:path_color="@color/two_way"
      lib:line_size="0.05"
      lib:stroke_width="3sp"
      lib:left_line_animation_time="2800"
      lib:left_line_max_size="0.5"
      lib:left_line_animation_start_delay="2500"
      lib:right_line_animation_start_delay="2000"
      lib:right_line_max_size="0.5"
      lib:right_line_animation_time="2000"
      lib:path_data="@string/github"
      lib:path_original_width="@integer/github_original_width"
      lib:path_original_height="@integer/github_original_height"
      lib:path_animation_type="twoWay"
      />

Material

<com.github.glomadrian.roadrunner.IndeterminateRoadRunner
     android:id="@+id/material"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     lib:movement_direction="counter_clockwise"
     lib:path_color="#FFFFFF"
     lib:stroke_width="3sp"
     lib:path_data="@string/twitter"
     lib:path_original_width="@integer/twitter_original_width"
     lib:path_original_height="@integer/twitter_original_height"
     lib:path_animation_type="material"
     />

Determinate Two way

<com.github.glomadrian.roadrunner.DeterminateRoadRunner
    android:id="@+id/determinate"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    lib:min="0"
    lib:max="100"
    lib:movement_direction="counter_clockwise"
    lib:path_color="@color/colorAccent"
    lib:stroke_width="2sp"
    lib:movement_loop_time="1500"
    lib:path_data="@string/clip"
    lib:path_original_width="@integer/clip_original_width"
    lib:path_original_height="@integer/clip_original_height"
    lib:animate_on_start="false"
    />

Custom attributes

Common

  • movement_direction: clockwise or counter_clockwise
  • path_color: color of the painted path
  • stroke_width: width of the painted path
  • path_data: String with the path information
  • path_original_width: The original with defined in the SVG
  • path_original_height: The original height defined in the SVG
  • animate_on_start: true or false, init the animation on first paint (true by default)

Indeterminate

  • path_animation_type: Select indetermina animation type, can be:
    • material
    • twoWay

Indeterminate Material

  • Dont have any custom attributes

Indeterminate Two way

  • movement_loop_time:** Time take to do a complete loop
  • line_size:* The size of the base line
  • left_line_animation_time: Time take to do a complete animation to the left line
  • right_line_animation_time: Time take to do a complete animation to the right line
  • left_line_max_size:* The max size that the left line can research in the animation
  • right_line_max_size:* The max size that the right line can research in the animation
  • left_line_animation_start_delay: Time to wait to start the left line animation (in milliseconds)
  • right_line_animation_start_delay: Time to wait to start the right line animation (in milliseconds)

* From 0f to 1f, 1f is all the path

Determinate

  • min: Min value for the progress
  • max: Max value for the progress
  • movement_loop_time: Time take to do a complete loop
  • movement_line_size:* The size of the line

* From 0f to 1f, 1f is all the path

Attributions

For Gradle

Add repository

repositories {
  maven {
    url "http://dl.bintray.com/glomadrian/maven"
  }
}

Add dependency

compile 'com.github.glomadrian:roadrunner:1.0@aar'

Developed By

Adrián García Lomas - [email protected]

License

Copyright 2016 Adrián García Lomas

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • ProgressRoadRunner

    ProgressRoadRunner

    Hey,

    I just created a progress implementation of your great library. I am not sure if the way i did, was correct way to do it though. But as i follow up your code i managed it, so take a look at it please. And if you can implement this option to other RoadRunner types as well, that would be actually great. Maybe you can create much more generic way then i did, i just needed this implementation so i modified it quickly.

    opened by yayaa 6
  • NullPointerException

    NullPointerException

    java.lang.NullPointerException: Attempt to invoke interface method 'void com.github.glomadrian.roadrunner.painter.determinate.DeterminatePathPainter.paintPath(android.graphics.Canvas)' on a null object reference at com.github.glomadrian.roadrunner.DeterminateRoadRunner.onDraw(DeterminateRoadRunner.java:105)

    opened by Isabellle 0
  • NullPointerException

    NullPointerException

    Hello, I am getting a null pointer exception when I try to invoke the start method on the object. I have it defined in the xml to match your sample exactly. In the java, it looks like this:

    https://gist.github.com/PGMacDesign/cc08dda8b5e177dda770fea51fa05c53

    Any clue as to why the stacktrace is reading this? :

    07-26 09:19:20.114 2860-2860/com.testing.stuff E/UncaughtException: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mastermatchmakers.trust.lovelab/com.mastermatchmakers.trust.lovelab.misc.TestActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.github.glomadrian.roadrunner.painter.indeterminate.IndeterminatePathPainter.start()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5456) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.github.glomadrian.roadrunner.painter.indeterminate.IndeterminatePathPainter.start()' on a null object reference at com.github.glomadrian.roadrunner.IndeterminateRoadRunner.start(IndeterminateRoadRunner.java:110) at com.mastermatchmakers.trust.lovelab.misc.TestActivity.onCreate(TestActivity.java:80) at android.app.Activity.performCreate(Activity.java:6245) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)  at android.app.ActivityThread.-wrap11(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5456)  at java.lang.reflect.Method.invoke(Native Method) 

    opened by PGMacDesign 0
  • Error when used my path

    Error when used my path

    When I used my path(points) it crashes.

    Error 07-11 09:13:19.320 19436-19436/example.com.sampleprogress E/IndeterminateLoading: Path parse exception: java.text.ParseException: Expected command (at offset 0) at com.github.glomadrian.roadrunner.svg.SvgPathParser.consumeCommand(SvgPathParser.java:189) at com.github.glomadrian.roadrunner.svg.SvgPathParser.parsePath(SvgPathParser.java:63) at com.github.glomadrian.roadrunner.RoadRunner.parsePath(RoadRunner.java:47) at com.github.glomadrian.roadrunner.RoadRunner.buildPathData(RoadRunner.java:32) at com.github.glomadrian.roadrunner.IndeterminateRoadRunner.onSizeChanged(IndeterminateRoadRunner.java:91) at android.view.View.sizeChange(View.java:15743) at android.view.View.setFrame(View.java:15716) at android.view.View.layout(View.java:15632) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573) at android.widget.FrameLayout.onLayout(FrameLayout.java:508) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:435) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573) at android.widget.FrameLayout.onLayout(FrameLayout.java:508) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573) at android.widget.FrameLayout.onLayout(FrameLayout.java:508) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2072) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1829) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5786) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5289) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 07-11 09:13:19.321 19436-19436/example.com.sampleprogress D/AndroidRuntime: Shutting down VM 07-11 09:13:19.322 19436-19436/example.com.sampleprogress E/AndroidRuntime: FATAL EXCEPTION: main Process: example.com.sampleprogress, PID: 19436 java.lang.NullPointerException: Attempt to invoke interface method 'void com.github.glomadrian.roadrunner.painter.indeterminate.IndeterminatePathPainter.start()' on a null object reference at com.github.glomadrian.roadrunner.IndeterminateRoadRunner.onSizeChanged(IndeterminateRoadRunner.java:97) at android.view.View.sizeChange(View.java:15743) at android.view.View.setFrame(View.java:15716) at android.view.View.layout(View.java:15632) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573) at android.widget.FrameLayout.onLayout(FrameLayout.java:508) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:435) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573) at android.widget.FrameLayout.onLayout(FrameLayout.java:508) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573) at android.widget.FrameLayout.onLayout(FrameLayout.java:508) at android.view.View.layout(View.java:15636) at android.view.ViewGroup.layout(ViewGroup.java:4967) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2072) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1829) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5786) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5289) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

    My path 3.006,2.446 32.627,12.65 45.63,4.603 53.618,9.501 56.534,10.201 63.064,5.362 71.927,2.971 75.017,6.644 78.108,11.542 83.064,7.548 84.988,4.079 90.761,3.787 93.385,8.394 93.91,11.834 92.102,19.181 90.644,24.487 84.755,30.201 77.933,36.09 68.137,37.373 52.102,38.073 38.05,35.566 30.12,33.758 21.84,32.184 19.332,35.566 13.735,37.49 7.379,32.65 4.055,26.703 3.356,23.671 2.773,20.259 2.19,15.682 2.19,10.959 2.19,6.819 2.889,2.738

    opened by jainkuniya 1
  • Gradle Error:Could not find com.github.glomadrian:roadrunner:1.0. Required by project

    Gradle Error:Could not find com.github.glomadrian:roadrunner:1.0. Required by project

    Added the repository and aar as instructed, but I get Gradle Error:Could not find com.github.glomadrian:roadrunner:1.0. Required by project

    Seems like an awesome library, please help to compile. Btw I'm also using Android Annotations.

    opened by nishal 1
Owner
Adrián Lomas
Adrián Lomas
Chandrasekar Kuppusamy 799 Nov 14, 2022
Android Animation Easing Functions. Let's make animation more real!

Android Easing Functions This project is originally from my another project, AndroidViewAnimation, which is an animation collection, to help you make

代码家 2.5k Jan 4, 2023
This a demo application with animated SVG animation of Smiley

Animated-Smiley-Rating Animated Customer feedback and rating UI ?? License Copyright 2021 Aiman Muzafar Licensed under the Apache License, Version 2.0

Aiman Muzafar 12 Aug 12, 2021
Android loading animation with images changing

Android loading animation with images changing

Cüneyt Çarıkçi 109 Nov 29, 2022
Android library to make notes drop animation for music players

VusikView Min SDK 11 Screnshots How to use If you want use this library, you can download project and import it into your workspace and add the projec

Chetan Kaushik 119 Nov 29, 2022
Material image loading implementation

MaterialImageLoading Material image loading implementation Sample And have a look on a sample Youtube Video : Youtube Link [] (https://www.youtube.com

Florent CHAMPIGNY 392 Nov 17, 2022
A Simple Todo app design in Flutter to keep track of your task on daily basis. Its build on BLoC Pattern. You can add a project, labels, and due-date to your task also you can sort your task on the basis of project, label, and dates

WhatTodo Life can feel overwhelming. But it doesn’t have to. A Simple To-do app design in flutter to keep track of your task on daily basis. You can a

Burhanuddin Rashid 1k Jan 1, 2023
FadingToolbar is an animation library which fades out your footer view in a ScrollView/RecyclerView and fades in a toolbar title

FadingToolbar is an animation library which fades out your footer view in a ScrollView/RecyclerView and fades in a toolbar title (analogue of the LargeTitle animation in iOS)

Hanna 9 Nov 3, 2022
ActSwitchAnimTool make the Animation easy to implements, and it compat the version of Android 4.0 or above.

ActSwitchAnimTool As well as we know, Android 5.0 has been support more Animation(just like ViewAnimationUtils~). Maybe some developers can implements

Acropolis 573 Nov 23, 2022
Android view with both path from constructed path or from svg.

android-pathview You want to animate svg or normal Paths?<br> Change the color, pathWidth or add svg.<br> Animate the "procentage" property to make th

Georgi Eftimov 2.9k Dec 30, 2022
PaintableVectorView enables to change color of paths/groups in Vector Drawable (SVG)

PaintableVectorView PaintableVectorView enables to change color of paths/groups in Vector Drawable (SVG) Demo Car icon made by Prosymbols from www.fla

Jakub Anioła 164 Dec 16, 2022
A mix of random small libraries for Kotlin, the smallest reside here until big enough for their own repository.

klutter Random small libraries, usually extensions making other libraries happier. Versions later than 2.x are for JDK 8 and newer only. Maven Depende

Kohesive 140 Nov 1, 2022
A simple and customizable Android full-screen image viewer with shared image transition support, "pinch to zoom" and "swipe to dismiss" gestures

Stfalcon ImageViewer A simple and customizable full-screen image viewer with shared image transition support, "pinch to zoom" and "swipe to dismiss" g

Stfalcon LLC 1.9k Jan 5, 2023
Image-search - An Image search android app with offline support

image-search Image search app built using bing image search API via paging 3. Fe

Suraj Vaishnav 3 Feb 17, 2022
AndroidPhotoFilters aims to provide fast, powerful and flexible image processing instrument for creating awesome effects on any image media.

PhotoFiltersSDK PhotoFiltersSDK aims to provide fast, powerful and flexible image processing instrument for creating awesome effects on any image medi

Zomato 2.5k Dec 23, 2022
With MVVM Architecture pattern using Android Architecture Components This is a sample app demonstrating Youtube player animation using constraint layout

Youtube UI/UX Animation This is a sample app demonstrating Youtube UX/UI animation using ConstraintLayout.It implements the Keyframe Animation feature

Burhanuddin Rashid 866 Dec 29, 2022
🪐 Jetpack Compose animation library that allows you to implement animations such as shared element transition.

Orbitary ?? Jetpack Compose animation library that allows you to implement animations such as shared element transition. Download Gradle Add the depen

Jaewoong Eum 503 Dec 30, 2022
🪐 Jetpack Compose animation library that allows you to implement animations such as shared element transition.

?? Jetpack Compose animation library that allows you to implement animations such as shared element transition.

Jaewoong Eum 504 Jan 2, 2023
A component for flip animation on Android, which is similar to the effect in Flipboard iPhone/Android

android-flip Aphid FlipView is a UI component to accomplish the flipping animation like Flipboard does. A pre-built demo APK file for Android OS 2.2+

Bo 2.8k Dec 21, 2022