urbanairship / android-library

Urban Airship Android SDK
Other
109 stars 123 forks source link

Android in-app looks like IOS banner #151

Closed Hema2810 closed 4 years ago

Hema2810 commented 4 years ago

❗For how-to inquiries involving Airship functionality or use cases, please contact (support)[https://support.airship.com/].

Preliminary Info

What Airship dependencies are you using?

What are the versions of any relevant development tools you are using?

Report

What unexpected behavior are you seeing?

According to this https://docs.airship.com/reference/messages/message-types/in-app-messages/#style-banner Android is supposed to receive the in- app messages which looks more like a snackbar, but the ones I receive look more like the IOS drawer.

What is the expected behavior?

Should receive the in-app message like it is specified in the document

What are the steps to reproduce the unexpected behavior?

Implement the sdk in any android project and send a in-app message

Do you have logging for the issue?

BrianBatchelder commented 4 years ago

@Hema2810 : Banner messages can be placed at the top or the bottom of the screen. They are not intended to float on the screen as do Android snackbars or toasts. You might look at Modal messages, which appear in the middle of the screen.

Hema2810 commented 4 years ago

@BrianBatchelder Yes I need them on the top and bottom of the screen. But when you look at the documentation the default presentation is different from that of IOS. Is there a way to get it without custom implementation. Refer to the image I posted below from the document

On Tue, May 12, 2020, 6:00 PM Brian Batchelder notifications@github.com wrote:

@Hema2810 https://github.com/Hema2810 : Banner messages can be placed at the top or the bottom of the screen. They are not intended to float on the screen as do Android snackbars or toasts. You might look at Modal messages https://docs.airship.com/reference/messages/message-types/in-app-messages/#style-modal, which appear in the middle of the screen.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/urbanairship/android-library/issues/151#issuecomment-627644811, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHNSVPLRXHU5KCE627VUHBDRRHIKNANCNFSM4M7HDSBA .

Hema2810 commented 4 years ago

Screen Shot 2020-05-12 at 6 13 16 PM

BrianBatchelder commented 4 years ago

@Hema2810 : I'm re-opening this issue as I see now that the images of Android banner messages in the docs don't match what the SDK actually produces. I will get back to you soon about this.

BrianBatchelder commented 4 years ago

Turns out the images you are referring to are for our legacy "Standard In-App Messages", and, unfortunately, the images are also out-of-date. I'm afraid the only way for you to get the messages to appear like you want on Android is to implement a custom message adapter.

In the meantime, we will update our documentation. Thank you for pointing it out.

Hema2810 commented 4 years ago

Thank you for the response. Another problem I noticed was that when the app uses transparent navigation bar, the in app message appear over it and there is no way to click on the message. There should at least be a way to display the message above the navigation bar, but I do not find any such option.

Hema2810 commented 4 years ago

and also these links do no work Screen Shot 2020-05-12 at 8 54 15 PM in here https://docs.airship.com/platform/android/in-app-automation/

Hema2810 commented 4 years ago

And the UA dashboard also needs to be updated Screen Shot 2020-05-12 at 9 20 31 PM,

Hema2810 commented 4 years ago

@BrianBatchelder considering the dashboard is not also updated, I would not consider this issue as closed. It creates quite a bit of confusion. From what I see ,there is no option but to go for custom for Android, which takes the "easy of use" out for Android. I would really appeal to the team to consider it for future release. Let me know if I need to open a new issue.

BrianBatchelder commented 4 years ago

@Hema2810 Thank you for all the feedback. We will update the docs and dashboard to match our current behavior (and fix the links). I will also look into the issue with transparent navigation bars. I will also pass along your request to provide a mechanism to display Android messages that look more like a snackbar. I'll keep this ticket open so we can notify you when we have updated the docs and dashboard.

Hema2810 commented 4 years ago

Thank you! Appreciate the quick response.

BrianBatchelder commented 4 years ago

Another problem I noticed was that when the app uses transparent navigation bar, the in app message appear over it and there is no way to click on the message. There should at least be a way to display the message above the navigation bar, but I do not find any such option.

I have been unable to reproduce this. In my testing, the message always appears in front of the navigation bar, and is clickable. Can you provide me with more details?

Hema2810 commented 4 years ago

I have two apps which use the sdk and in both the message appears behind the navigation bar.

Screen Shot 2020-05-13 at 10 24 04 PM

Screen Shot 2020-05-13 at 10 22 13 PM.

Hema2810 commented 4 years ago

Just to give an update, both apps use full screen. I do not have issue on older phones which have physical button and do not have navigation bar on the screen. Only on newer phones with the navigation bars on the screen. Especially in apps which use full screen with transparent/translucent, navigation bars/ status bars.

BrianBatchelder commented 4 years ago

@Hema2810 : could you provide the version(s) of Android on which you are seeing the navigation bar issue? Thanks.

Hema2810 commented 4 years ago

I see the issue on Android 10 on my pixel 3. Could be on other versions and device, but currently noticed on this, would have to test the others.

rlepinski commented 4 years ago

@Hema2810 I was able to reproduce and fix your issue with the window insets on Android 10. Fix will go out in the next patch release. I will work on docs next. If you want the style sheets for the banner, it can be located here.

We filed an issue with our web team about the outdated preview, and sent your feedback about the design to the product manager.

I tried out making the banner into a card view, while keeping most if not all the style options for IAA. I am sure you could optimize the view based on your usage, but this reuses as much as I could from the SDK.

layout/card_banner.xml

<?xml version="1.0" encoding="utf-8"?>
<com.urbanairship.iam.banner.BannerDismissLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:fitsSystemWindows="true">

    <androidx.cardview.widget.CardView
        android:id="@+id/card"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center|bottom"
        android:layout_margin="16dp"
        android:minWidth="300dp">

        <ImageButton
            android:id="@+id/close"
            style="@style/Widget.AppCompat.Button.Borderless"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_gravity="top|right"
            android:padding="4dp"
            android:src="@drawable/ua_ic_close_white" />

        <com.urbanairship.iam.view.BoundedLinearLayout
            android:id="@+id/banner"
            urbanAirshipMaxWidth="420dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_margin="8dp"
            android:orientation="vertical">

            <ViewStub
                android:id="@+id/banner_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:inflatedId="@+id/ua_iam_banner_content_left_image" />

            <com.urbanairship.iam.view.InAppButtonLayout
                android:id="@+id/buttons"
                style="@style/UrbanAirship.InAppBanner.ButtonLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </com.urbanairship.iam.view.BoundedLinearLayout>

    </androidx.cardview.widget.CardView>
</com.urbanairship.iam.banner.BannerDismissLayout>

CardBannerView.kt:

class CardBannerView(context: Context, displayContent: BannerDisplayContent, private val assets: Assets?) : BannerView(context, displayContent, assets) {

    @MainThread
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
        val view = inflater.inflate(R.layout.card_banner, container, false) as BannerDismissLayout
        view.setPlacement(displayContent.placement)
        view.setListener(this)

        val cardView = view.findViewById(R.id.card) as CardView
        cardView.setCardBackgroundColor(displayContent.backgroundColor)
        cardView.radius = displayContent.borderRadius
        cardView.z = 8f

        val closeButton = view.findViewById(R.id.close) as ImageButton
        val dismissDrawable = DrawableCompat.wrap(closeButton.drawable).mutate()
        DrawableCompat.setTint(dismissDrawable, displayContent.dismissButtonColor)
        closeButton.setImageDrawable(dismissDrawable)
        closeButton.setOnClickListener {
            dismiss(false)
        }

        val layoutParams = cardView.layoutParams as LayoutParams
        if (displayContent.placement == BannerDisplayContent.PLACEMENT_TOP) {
            layoutParams.gravity = Gravity.CENTER or Gravity.TOP
        } else {
            layoutParams.gravity = Gravity.CENTER or Gravity.BOTTOM
        }
        cardView.layoutParams = layoutParams

        // Inflate the banner content
        val bannerContent = view.findViewById<ViewStub>(R.id.banner_content)
        bannerContent.layoutResource = getContentLayout()
        bannerContent.inflate()

        if (displayContent.actions.isNotEmpty()) {
            view.isClickable = true
            view.setOnClickListener(this)
        }

        // Heading
        val heading = view.findViewById(R.id.heading) as TextView
        if (displayContent.heading != null) {
            InAppViewUtils.applyTextInfo(heading, displayContent.heading!!)
        } else {
            heading.visibility = View.GONE
        }

        // Body
        val body = view.findViewById(R.id.body) as TextView
        if (displayContent.body != null) {
            InAppViewUtils.applyTextInfo(body, displayContent.body!!)
        } else {
            body.visibility = View.GONE
        }

        // Media
        val mediaView: MediaView = view.findViewById(R.id.media) as MediaView
        if (displayContent.media != null) {
            InAppViewUtils.loadMediaInfo(mediaView, displayContent.media!!, assets)
        } else {
            mediaView.visibility = View.GONE
        }

        // Button Layout
        val buttonLayout: InAppButtonLayout = view.findViewById(R.id.buttons)
        if (displayContent.buttons.isEmpty()) {
            buttonLayout.visibility = View.GONE
        } else {
            buttonLayout.setButtons(displayContent.buttonLayout, displayContent.buttons)
            buttonLayout.setButtonClickListener(this)
        }

        view.addOnAttachStateChangeListener(object : OnAttachStateChangeListener {
            override fun onViewAttachedToWindow(view: View) {
                ViewCompat.requestApplyInsets(view)
            }

            override fun onViewDetachedFromWindow(view: View) {
                view.removeOnAttachStateChangeListener(this)
            }
        })

        ViewCompat.setOnApplyWindowInsetsListener(view) { v, src ->
            val copy = WindowInsetsCompat(src)
            ViewCompat.onApplyWindowInsets(v, copy)
            src
        }
        return view
    }

    /**
     * Gets the banner content layout for the banner's template.
     *
     * @return The banner template layout.
     */
    @LayoutRes
    private fun getContentLayout(): Int {
        return when (displayContent.template) {
            BannerDisplayContent.TEMPLATE_RIGHT_MEDIA -> R.layout.ua_iam_banner_content_right_media
            BannerDisplayContent.TEMPLATE_LEFT_MEDIA -> R.layout.ua_iam_banner_content_left_media
            else -> R.layout.ua_iam_banner_content_left_media
        }
    }
}

CardBannerAdapter.kt:

class CardBannerAdapter(message: InAppMessage, private val displayContent: BannerDisplayContent) : BannerAdapter(message, displayContent) {
        override fun onCreateView(activity: Activity, viewGroup: ViewGroup): BannerView {
            return CardBannerView(activity, displayContent, assets)
        }
    }

In Autopilot, override the banner factory:

        InAppMessageManager.shared().setAdapterFactory(InAppMessage.TYPE_BANNER) {
            CardBannerAdapter(it, it.getDisplayContent()!!)
        }

device-2020-05-18-141720

Hema2810 commented 4 years ago

@rlepinski , thank you for the update.

rlepinski commented 4 years ago

Fixed in 13.1.1