Skip to content

Commit

Permalink
feat(android): support drawable in ImageSource (#10098)
Browse files Browse the repository at this point in the history
This allows passing a drawable as another source option
  • Loading branch information
triniwiz committed Nov 20, 2022
1 parent 6c60eab commit 75eefa6
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 1 deletion.
31 changes: 31 additions & 0 deletions apps/automated/src/image-source/image-source-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as app from '@nativescript/core/application';
import * as TKUnit from '../tk-unit';
import { Font } from '@nativescript/core/ui/styling/font';
import { Color } from '@nativescript/core/color';
import * as utils from '@nativescript/core/utils';

const imagePath = '~/assets/logo.png';
const splashscreenPath = '~/assets/splashscreen.png';
Expand All @@ -20,6 +21,36 @@ export function testFromResource() {
TKUnit.assert(img.height > 0, 'image.fromResource failed');
}

export function testDrawableSetNativeSource() {
if (global.isAndroid) {
const context = utils.ad.getApplicationContext() as android.content.Context;
const rDrawable = `${context.getPackageName()}.R$drawable`;
const rClazz = java.lang.Class.forName(`${rDrawable}`);
const iconId = rClazz.getDeclaredField('icon').get(null) as java.lang.Integer;
const splashScreenId = rClazz.getDeclaredField('splash_screen').get(null) as java.lang.Integer;

const icon = androidx.appcompat.content.res.AppCompatResources.getDrawable(context, iconId?.intValue?.() ?? 0);
const splashScreen = androidx.appcompat.content.res.AppCompatResources.getDrawable(context, splashScreenId?.intValue?.() ?? 0);

let type = icon?.getClass?.().toString?.() ?? '';

// >> imagesource-setNativeSource
const img = new ImageSource();
img.setNativeSource(icon);
// << imagesource-setNativeSource

TKUnit.assert(img.height > 0, `image ${type} setNativeSource failed`);

type = splashScreen?.getClass?.().toString?.() ?? '';

// >> imagesource-setNativeSource
img.setNativeSource(splashScreen);
// << imagesource-setNativeSource

TKUnit.assert(img.height > 0, `image ${type} setNativeSource failed`);
}
}

export function testFromUrl(done) {
let result: ImageSource;

Expand Down
7 changes: 6 additions & 1 deletion packages/core/image-source/index.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,13 @@ export class ImageSource implements ImageSourceDefinition {

public setNativeSource(source: any): void {
if (source && !(source instanceof android.graphics.Bitmap)) {
throw new Error('The method setNativeSource() expects android.graphics.Bitmap instance.');
if (source instanceof android.graphics.drawable.Drawable) {
this.android = org.nativescript.widgets.Utils.getBitmapFromDrawable(source);
return;
}
throw new Error('The method setNativeSource() expects an android.graphics.Bitmap or android.graphics.drawable.Drawable instance.');
}

this.android = source;
}

Expand Down
Binary file modified packages/core/platforms/android/widgets-release.aar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ declare module org {
export module widgets {
export class Utils {
public static class: java.lang.Class<org.nativescript.widgets.Utils>;
public static getBitmapFromDrawable(param0: globalAndroid.graphics.drawable.Drawable): globalAndroid.graphics.Bitmap;
public static getBitmapFromView(param0: globalAndroid.view.View): globalAndroid.graphics.Bitmap;
public static loadImageAsync(param0: globalAndroid.content.Context, param1: string, param2: string, param3: number, param4: number, param5: org.nativescript.widgets.Utils.AsyncImageCallback): void;
public static drawBoxShadow(param0: globalAndroid.view.View, param1: string): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
Expand Down Expand Up @@ -70,6 +72,7 @@ private static Bitmap drawBitmap(View view) {
return bitmap;
}

@SuppressWarnings("deprecation")
public static Bitmap getBitmapFromView(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return drawBitmap(view);
Expand All @@ -88,6 +91,28 @@ public static Bitmap getBitmapFromView(View view) {
}
}

public static Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
} else {
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Rect previousBounds = null;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
previousBounds = drawable.getBounds();
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}

drawable.draw(canvas);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
drawable.setBounds(previousBounds);
}
return bitmap;
}
}

public static void drawBoxShadow(View view, String value) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
return;
Expand Down

0 comments on commit 75eefa6

Please sign in to comment.