Skip to content

Android: Layout Customization

Amit Davidi edited this page May 18, 2017 · 1 revision

The library's Android code has been OO-designed, making it flexible and customizable so-as to allow developers to tailor it into their specific project needs -- such as custom notification layouts.

Customizing Notifications Layout

The Android notifications SDK is feature-rich and allows far more than the plain title/message layout provided by the framework as a default:

Here are a few example (taken from Google's developers guide):

Any of these examples (extended layouts, custom icons, buttons and more) can be easily applied by framework users. We'll use the first notification (titled The Big Meeting) as a reference to explain how (under the assumption that content - title and message, are provided by the incoming notification data).

Step 1: Custom Push-Notification Class

All of the notification handling business logic is done by the PushNotification class. The first step is to inherit your version of it, overriding it's getNotificationBuilder() method, which is a "hook" for definiting notification layout and behavior.

/**
 * Overrides the default PushNotification implementation to create a
 * notification with a layout similar to the 'The Big Meeting' notification,
 * showing in the screenshot above.
 */
public class MyPushNotification extends PushNotification {

    public MyPushNotification(Context context, Bundle bundle, AppLifecycleFacade appLifecycleFacade, AppLaunchHelper appLaunchHelper, JsIOHelper jsIoHelper) {
        super(context, bundle, appLifecycleFacade, appLaunchHelper, jsIoHelper);
    }

    @Override
    protected Notification.Builder getNotificationBuilder(PendingIntent intent) {
        final Resources resources = mContext.getResources();

        // First, get a builder initialized with defaults from the core class.
        final Notification.Builder builder = super.getNotificationBuilder(intent);

        // Set our custom overrides --

        // Enable 'extended' layout (extends on down-stroke gesture):
        final Notification.BigTextStyle extendedNotificationStyle =
                new Notification.BigTextStyle()
                    .bigText(mNotificationProps.getBody()); // "4:15 - 5:15 PM\nBig Conference Room"
        builder.setStyle(extendedNotificationStyle);

        // Set custom-action icon.
        builder.setSmallIcon(R.drawable.meeting_icon)
                .setColor(resources.getColor(R.color.notification_bkg_color)); // Blue-ish

        // Add 'map' action.
        Notification.Action openMapAction = new Notification.Action(
                R.drawable.action_map,
                resources.getString(R.string.action_map),
                MyIntentUtils.getMapIntent(mNotificationProps.asBundle().getString("location")));
        builder.addAction(openMapAction);

        // Add 'email guests' action.
        Notification.Action emailGuestsAction = new Notification.Action(
                R.drawable.action_email_guests,
                resources.getString(R.string.action_email_guests),
                MyIntentUtils.getComposeEmailIntent(mNotificationProps.asBundle().getStringArrayList("invited")));
        builder.addAction(emailGuestsAction);

        return builder;
    }
}

Step 2: Push Notifications Class Registration

Declare your application class to implement INotificationsApplication:

public class MainApplication
	extends Application
	implements ReactApplication,
              INotificationsApplication // Label-interface telling the framework you have a custom notification class
{
	// ...
	
    /**
     * Implementation of INotificationsApplication:
     * Overridden to return our custom {@linkplain MyPushNotification} class instead of
     * the default {@linkplain com.wix.reactnativenotifications.core.notification.PushNotification}.
     */
    @Override
    public IPushNotification getPushNotification(Context context, Bundle bundle, AppLifecycleFacade defaultFacade, AppLaunchHelper defaultAppLaunchHelper) {
        return new MyPushNotification(context, bundle, defaultFacade, defaultAppLaunchHelper, new JsIOHelper());
    }
}

Pro Tip! Create Your Own Custom PushNotificationProps

You might have noticed that in order to retrieve the meeting's location and list of invited guests when building the notification we referred to mNotificationProps.asBundle(), consequently applying Bundle methods such as getString(). Getting the notification body-text, however, was easier to do - we simply used mNotificationProps.getBody().

It's recommended that you'd apply the getBody() convenience practice over data you expect the notifications sent by your server (for example, location). This can be done by overriding the PushNotificationProps class, as follows:

public class MyPushNotificationProps extends PushNotificationProps {

    public MyPushNotificationProps(Bundle bundle) {
        super(bundle);
    }

    public String getLocation() {
        return mBundle.getString("location");
    }

    public List<String> getInvitedGuests() {
    	List<String> guests = mBundle.getStringArrayList("invited");
    	return guests == null ? Collections.emptyList() : guests;
    }

    @Override
    protected MyPushNotificationProps copy() {
        return new MyPushNotificationProps((Bundle) mBundle.clone());
    }
}

To register the creation of MyPushNotificationProps instead of the default PushNotificationProps, override PushNotification.createProps():

    @Override
    protected PushNotificationProps createProps(Bundle bundle) {
        return new MyPushNotificationProps(bundle);
    }

    /** A convenience: */
    protected MyPushNotificationProps getProps() {
        return (MyPushNotificationProps) mNotificationProps;
    }