Vamsi Challa Vamsi Challa - 19 days ago 8
Android Question

JorgeCastilloPrz's AndroidFillableLoaders Library - SVGPath issue

[EDIT]
The solution of @antonio works. See the screeshots below for proof..




I am trying to use JorgeCastilloPrz's AndroidFillableLoaders Library and this is the first time i am using SVG(or Path for that matter). So please bear with me if the question is too naive.

Library Link: https://github.com/JorgeCastilloPrz/AndroidFillableLoaders

Code:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rl_root_splash_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/splash_screen_color_1"
android:paddingBottom="100dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">

<com.github.jorgecastillo.FillableLoader
android:id="@+id/fillableLoader"
android:layout_width="200dp"
android:layout_height="100dp"
app:fl_clippingTransform="waves"
app:fl_fillColor="#1c9ade"
app:fl_fillDuration="5000"
app:fl_originalHeight="970"
app:fl_originalWidth="970"
app:fl_strokeColor="#1c9ade"
app:fl_strokeDrawingDuration="2000"
app:fl_strokeWidth="16dp" />

</RelativeLayout>


I am using the INDOMINOUS_REX string from the sample app in library as the SVG Path. Link: https://github.com/JorgeCastilloPrz/AndroidFillableLoaders/blob/master/sampleapp/src/main/java/com/github/jorgecastillo/Paths.java

MainActivity.java

public class SplashActivity extends AppCompatActivity {

RelativeLayout rlRoot;
FillableLoader fillableLoader;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);

rlRoot = (RelativeLayout) findViewById(R.id.rl_root_splash_activity);

FillableLoaderBuilder loaderBuilder = new FillableLoaderBuilder();
fillableLoader = loaderBuilder
.parentView(rlRoot)
.svgPath(Const.Paths.INDOMINUS_REX)
.layoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT))
.originalDimensions(970, 970)
.strokeColor(Color.parseColor("#1c9ade"))
.fillColor(Color.parseColor("#1c9ade"))
.strokeDrawingDuration(2000)
.clippingTransform(new WavesClippingTransform())
.fillDuration(10000)
.build();

}

}


When i run the code, i get the following exception:

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at com.github.jorgecastillo.svg.SvgPathParser.parsePath(SvgPathParser.java:52)
at com.github.jorgecastillo.FillableLoader.buildPathData(FillableLoader.java:374)
at com.github.jorgecastillo.FillableLoader.onSizeChanged(FillableLoader.java:224)
at android.view.View.sizeChange(View.java:16748)
at android.view.View.setFrame(View.java:16710)
at android.view.View.layout(View.java:16627)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2678)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1931)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)


Can someone help me in figuring this out?




The solution of @antonio works and here is the proof...

enter image description here

enter image description here

enter image description here

Answer

The NPE occurs because you have defined a com.github.jorgecastillo.FillableLoader in your R.layout.activity_splash but you haven't programmatically set the generated path. From the documentation

To set the generated path by code (do it just if you declared FillableLoader in the xml layout):

fillableLoader.setSvgPath(String generatedSvgPath);

To solve it, your onCreate can be like this:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    rlRoot = (RelativeLayout) findViewById(R.id.rl_root_splash_activity);

    fillableLoader = (FillableLoader) findViewById(R.id.fillableLoader);
    fillableLoader.setSvgPath(Const.Paths.INDOMINUS_REX);
}

Note that you have defined a FillableLoader both in your layout and programmatically, but the definition that is causing the NPE is the one in the layout because it lacks the setSvgPath.


Other option is removing the FillableLoader definition from your layout as you are programmatically generating it using a FillableLoaderBuilder:

activity_splash.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/rl_root_splash_activity"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/splash_screen_color_1"
            android:paddingBottom="100dp"
            android:paddingEnd="16dp"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:paddingStart="16dp">
</RelativeLayout>

SplashActivity.onCreate method

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rlRoot = (RelativeLayout) findViewById(R.id.rl_root_splash_activity);

    FillableLoaderBuilder loaderBuilder = new FillableLoaderBuilder();
    fillableLoader = loaderBuilder
            .parentView(rlRoot)
            .svgPath(Const.Paths.INDOMINUS_REX)
            .layoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT))
            .originalDimensions(970, 970)
            .strokeColor(Color.parseColor("#1c9ade"))
            .fillColor(Color.parseColor("#1c9ade"))
            .strokeDrawingDuration(2000)
            .clippingTransform(new WavesClippingTransform())
            .fillDuration(10000)
            .build();
    fillableLoader.setSvgPath(Paths.INDOMINUS_REX);
}

Note that in both cases you will need to call fillableLoader.start(); to see the animation.