Carousel Push functionality allows you to show your notification with a slideshow.
Requirements
- Android SDK 2.0.0+
Before you start, you need to define your receiver in your manifest file.
Defining Custom Receiver
<receiver android:name=".MyReceiver"
android:exported="false"> <!-- change NotificationReceiver to .MyReceiver -->
<intent-filter>
<action android:name="com.dengage.push.intent.RECEIVE" />
<action android:name="com.dengage.push.intent.OPEN" />
<action android:name="com.dengage.push.intent.DELETE" />
<action android:name="com.dengage.push.intent.ITEM_CLICK" /> <!-- add this line-->
<action android:name="com.dengage.push.intent.CAROUSEL_ITEM_CLICK" /><!-- add this line-->
<action android:name="com.dengage.push.intent.ACTION_CLICK" />
</intent-filter>
</receiver>
Preparing Custom Layouts
The SDK uses a custom layout for the functionality. It means you need to set your layout first in your res folder. At the same time, We prepared 2 pre-build layouts that you can easily use;
- Landscape
- Portrait
To use them, Please add _den_carousel_landscape.xml or dencarousel_portrait.xml file to your layouts directory.
den_carousel_landscape.xml
Note: You will need to change drawable items with yours.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/den_carousel_collapsed"
layout="@layout/den_carousel_collapsed"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@+id/den_carousel_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/den_carousel_collapsed"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<ImageView
android:id="@+id/den_carousel_landscape_image"
android:layout_width="match_parent"
android:layout_height="160dp"
android:scaleType="centerCrop"
android:layout_gravity="center"
/>
<ImageView
android:id="@+id/den_carousel_left_image"
android:layout_width="44dp"
android:layout_height="44dp"
android:src="@drawable/ic_carousal_left_arrow"
android:layout_gravity="start|center_vertical"
android:scaleType="fitXY"
android:layout_marginStart="5dp" />
<ImageView
android:id="@+id/den_carousel_right_image"
android:layout_width="44dp"
android:layout_height="44dp"
android:src="@drawable/ic_carousal_right_icon"
android:layout_gravity="end|center_vertical"
android:scaleType="fitXY"
android:layout_marginEnd="5dp" />
</FrameLayout>
<LinearLayout android:id="@+id/den_carousel_item_title_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="@id/den_carousel_frame"
android:layout_marginTop="5dp"
>
<TextView
android:id="@+id/den_carousel_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Item Title"
/>
</LinearLayout>
<LinearLayout android:id="@+id/den_carousel_item_description_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_below="@id/den_carousel_item_title_container"
>
<TextView
android:id="@+id/den_carousel_item_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Item Description" />
</LinearLayout>
</RelativeLayout>
den_carousel_portrait.xml
Note: You will need to change drawable items with yours.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="320dp">
<include
android:id="@+id/den_carousel_collapsed"
layout="@layout/den_carousel_collapsed"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@+id/den_carousel_body_portrait"
android:layout_width="596dp"
android:layout_height="wrap_content"
android:layout_below="@id/den_carousel_collapsed"
android:layout_gravity="center"
android:layout_marginBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<RelativeLayout
android:id="@+id/den_carousel_left_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/den_carousel_portrait_current_container"
android:layout_toLeftOf="@+id/den_carousel_portrait_current_container">
<ImageView
android:id="@+id/den_carousel_portrait_left_image"
android:layout_width="192dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleType="centerCrop" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/den_carousel_portrait_left_image"
android:layout_alignStart="@+id/den_carousel_portrait_left_image"
android:layout_alignLeft="@+id/den_carousel_portrait_left_image"
android:layout_alignEnd="@+id/den_carousel_portrait_left_image"
android:layout_alignRight="@+id/den_carousel_portrait_left_image"
android:layout_alignTop="@+id/den_carousel_portrait_left_image"
android:background="#BFffffff" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/den_carousel_right_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/den_carousel_portrait_current_container"
android:layout_toRightOf="@+id/den_carousel_portrait_current_container">
<ImageView
android:id="@+id/den_carousel_portrait_right_image"
android:layout_width="192dp"
android:layout_height="192dp"
android:layout_centerInParent="true"
android:scaleType="centerCrop" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/den_carousel_portrait_right_image"
android:layout_alignStart="@+id/den_carousel_portrait_right_image"
android:layout_alignLeft="@+id/den_carousel_portrait_right_image"
android:layout_alignEnd="@+id/den_carousel_portrait_right_image"
android:layout_alignRight="@+id/den_carousel_portrait_right_image"
android:layout_alignTop="@+id/den_carousel_portrait_right_image"
android:background="#B0ffffff" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/den_carousel_portrait_current_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<ImageView
android:id="@+id/den_carousel_portrait_current_image"
android:layout_width="212dp"
android:layout_height="192dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:cropToPadding="true"
android:scaleType="centerCrop" />
</RelativeLayout>
</RelativeLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
<ImageView
android:id="@+id/den_carousel_left_arrow"
android:layout_width="44dp"
android:layout_height="44dp"
android:src="@drawable/ic_carousal_left_arrow"
android:layout_gravity="start|center_vertical"
android:scaleType="fitXY" />
<ImageView
android:id="@+id/den_carousel_right_arrow"
android:layout_width="44dp"
android:layout_height="44dp"
android:src="@drawable/ic_carousal_right_icon"
android:layout_gravity="end|center_vertical"
android:scaleType="fitXY" />
</FrameLayout>
</FrameLayout>
<LinearLayout android:id="@+id/den_carousel_item_title_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="@id/den_carousel_body_portrait"
>
<TextView
android:id="@+id/den_carousel_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Item Title"
/>
</LinearLayout>
<LinearLayout android:id="@+id/den_carousel_item_description_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="@id/den_carousel_item_title_container"
>
<TextView
android:id="@+id/den_carousel_item_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Item Description" />
</LinearLayout>
</RelativeLayout>
The above layout includes den_carousel_collapsed.xml file;
den_carousel_collapsed.xml
Note: You will need to change drawable items with yours.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<ImageView
android:id="@+id/den_carousel_image"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_gravity="top|end"
android:layout_marginLeft="12dp"
android:layout_marginStart="12dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_launcher_foreground" /> <!-- Your App Icon -->
<TextView
android:id="@+id/den_carousel_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/den_carousel_image"
android:layout_toLeftOf="@id/den_carousel_image"
android:text="Remote Title"
android:textSize="15dp"
android:textColor="@color/colorPrimary"
android:textStyle="bold" />
<TextView
android:id="@+id/den_carousel_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/den_carousel_title"
android:layout_alignStart="@+id/den_carousel_title"
android:layout_alignLeft="@+id/den_carousel_title"
android:layout_alignEnd="@+id/den_carousel_title"
android:layout_alignRight="@+id/den_carousel_title"
android:layout_toLeftOf="@id/den_carousel_image"
android:ellipsize="end"
android:lineSpacingMultiplier="1.2"
android:maxLines="1"
android:text="Remote message"
android:textSize="14dp"
android:textColor="@color/colorPrimary"
android:layout_marginBottom="16dp"/>
</RelativeLayout>
Please note that you can always edit these layouts or create a new one.
Building Notification
To use a custom layout for the notification requires building a message by the developer with the layout.
First, please create your receiver class extends from NotificationReceiver and override the methods below;
- onRender
- onReRender
class PushNotificationReceiver : NotificationReceiver() {
override fun onCarouselRender(context: Context, intent: Intent?, message: Message?) {
// build carousel message with a custom layout. In this case, we will use dengage_carousel_landscape.xml and dengage_carousel_portrait.xml files.
}
override fun onCarouselReRender(context: Context, intent: Intent?, message: Message?) {
// Re-build carousel message with a custom layout to slide item next/prev.
}
}
Building Carousel
Copy the codes below to your receiver class.
class PushNotificationReceiver : NotificationReceiver() {
override fun onCarouselRender(
context: Context,
intent: Intent,
message: Message,
leftCarouselItem: CarouselItem,
currentCarouselItem: CarouselItem,
rightCarouselItem: CarouselItem
) {
super.onCarouselRender(
context,
intent,
message,
leftCarouselItem,
currentCarouselItem,
rightCarouselItem
)
val itemTitle = currentCarouselItem.title
val itemDesc = currentCarouselItem.description
// set intents (right button, left button, item click)
val itemIntent = getItemClickIntent(intent.extras, context.packageName)
val leftIntent = getLeftItemIntent(intent.extras, context.packageName)
val rightIntent = getRightItemIntent(intent.extras, context.packageName)
val deleteIntent = getDeleteIntent(intent.extras, context.packageName)
val contentIntent = getContentIntent(intent.extras, context.packageName)
val carouseItemIntent = getPendingIntent(context, 0, itemIntent)
val carouselLeftIntent = getCarouselDirectionIntent(context, 1, leftIntent)
val carouselRightIntent = getCarouselDirectionIntent(context, 2, rightIntent)
val deletePendingIntent = getDeletePendingIntent(context, 4, deleteIntent)
val contentPendingIntent = getPendingIntent(context, 5, contentIntent)
// set views for the layout
val collapsedView = RemoteViews(
context.packageName,
R.layout.den_carousel_collapsed
)
collapsedView.setTextViewText(R.id.den_carousel_title, message.title)
collapsedView.setTextViewText(R.id.den_carousel_message, message.message)
val carouselView = RemoteViews(
context.packageName,
R.layout.den_carousel_portrait
)
carouselView.setTextViewText(R.id.den_carousel_title, message.title)
carouselView.setTextViewText(R.id.den_carousel_message, message.message)
carouselView.setTextViewText(R.id.den_carousel_item_title, itemTitle)
carouselView.setTextViewText(R.id.den_carousel_item_description, itemDesc)
carouselView.setOnClickPendingIntent(R.id.den_carousel_left_arrow, carouselLeftIntent)
carouselView.setOnClickPendingIntent(
R.id.den_carousel_portrait_current_image,
carouseItemIntent
)
carouselView.setOnClickPendingIntent(R.id.den_carousel_item_title, carouseItemIntent)
carouselView.setOnClickPendingIntent(R.id.den_carousel_item_description, carouseItemIntent)
carouselView.setOnClickPendingIntent(R.id.den_carousel_right_arrow, carouselRightIntent)
val channelId = createNotificationChannel(context, message)
loadCarouselImageToView(
carouselView = carouselView,
imageViewId = R.id.den_carousel_portrait_left_image,
carouselItem = leftCarouselItem,
onComplete = {
// you can call notificationManager.notify for devices that could not show carousel image contents
}
)
loadCarouselImageToView(
carouselView = carouselView,
imageViewId = R.id.den_carousel_portrait_current_image,
carouselItem = currentCarouselItem,
onComplete = {
// you can call notificationManager.notify for devices that could not show carousel image contents
}
)
loadCarouselImageToView(
carouselView = carouselView,
imageViewId = R.id.den_carousel_portrait_right_image,
carouselItem = rightCarouselItem,
onComplete = {
// you can call notificationManager.notify for devices that could not show carousel image contents
}
)
val notification = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setCustomContentView(collapsedView)
.setCustomBigContentView(carouselView)
.setContentIntent(contentPendingIntent)
.setDeleteIntent(deletePendingIntent)
.build()
// show message again silently with next, previous and current item.
notification.flags = Notification.FLAG_AUTO_CANCEL or Notification.FLAG_ONLY_ALERT_ONCE
// show message
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(
message.messageSource,
message.messageId,
notification
)
}