Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android in-app looks like IOS banner #151

Closed
Hema2810 opened this issue May 12, 2020 · 19 comments
Closed

Android in-app looks like IOS banner #151

Hema2810 opened this issue May 12, 2020 · 19 comments

Comments

@Hema2810
Copy link

❗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
Copy link
Contributor

@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
Copy link
Author

Hema2810 commented May 12, 2020 via email

@Hema2810
Copy link
Author

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

@BrianBatchelder
Copy link
Contributor

@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
Copy link
Contributor

BrianBatchelder commented May 13, 2020

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
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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

@Hema2810
Copy link
Author

Hema2810 commented May 13, 2020

@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
Copy link
Contributor

@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
Copy link
Author

Thank you! Appreciate the quick response.

@BrianBatchelder
Copy link
Contributor

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
Copy link
Author

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
Copy link
Author

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
Copy link
Contributor

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

@Hema2810
Copy link
Author

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
Copy link
Collaborator

@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
Copy link
Author

Hema2810 commented May 19, 2020

@rlepinski , thank you for the update.

@rlepinski
Copy link
Collaborator

Fixed in 13.1.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants