Android UX Views

Last Edit: Jun 06 2020

Logging, custom fonts and navigation can be configured at the client level.

Logging

By default logging is disabled. You can enable logs and set the log level when initializing Chat:


Chat chat = new Chat.Builder("api-key", context)
    .logLevel(ChatLogLevel.ALL)
    .build();
                    

val chat = Chat.Builder("api-key", context)
    .logLevel(ChatLogLevel.ALL)
    .build()
                    

If you need to intercept logs you can pass a logger handler:


Chat chat = new Chat.Builder("api-key", context)
    .loggerHandler(new ChatLoggerHandler() {
		@Override
        public void logI(@NotNull Object tag, @NotNull String message) {

        }
    })
    .build();
                    

val chat = Chat.Builder("api-key", context)
        .loggerHandler(object : ChatLoggerHandler {
            override fun logI(tag: Any, message: String) {
                
            }
        })
        .build()
                    

Custom fonts

You can set custom fonts for the entire library or for specific UI components. First of all you must put your own font file(s) (.ttf, .otf,…) in your assets or res folder.

Setup for whole library

You can register your custom fonts by StreamChat.initStyle(StreamChatStyle)


ChatStyle chatStyle = new ChatStyle.Builder()
        .setDefaultFont(R.font.custom_font)
        .build();

Chat chat = new Chat.Builder("api-key", context)
        .style(chatStyle)
        .build();
                    

val chatStyle = ChatStyle.Builder()
        .setDefaultFont(R.font.custom_font)
        .build()

val chat = Chat.Builder("api-key", context)
        .style(chatStyle)
        .build()
                    

Setup for specific UI components

Alternatively you can set custom fonts for specific UI components. Have a look at the font attributes for the custom view you're customizing.

The UI SDK has few builtin activities, webview and system browser Intents. Navigation between these components is handled internally by the StreamChatNavigator class. The concept is similar to the Google Navigation component:

  • ChatDestination represents a destination like the camera app or system web browser.

  • The SDK enables you to intercept destinations and handle them in a custom way.

  • Destination object provide the required information for navigation. For instance the WebLinkDestination has a url field which will be passed to system web browser.

The example below shows how you can open a custom webview when a user clicks on a link. It does this by overriding the behavior for  WebLinkDestination and AttachmentDestination:


Chat chat = new Chat.Builder("api-key", context)
        .navigationHandler(destination -> {
            String url = "";

            if (destination instanceof WebLinkDestination) {
                url = ((WebLinkDestination) destination).url;
            } else if (destination instanceof AttachmentDestination) {
                url = ((AttachmentDestination) destination).url;
            }

            if (url.startsWith("https://your.domain.com")) {
                Toast.makeText(context, "Custom url handling: " + url, Toast.LENGTH_SHORT).show();
                // handle/change/update url
                // open your webview, system browser or your own activity
                // and return true to override default behaviour
                return true;
            } else {
                return false;
            }
        })
        .build();
                    

val chat = Chat.Builder("api-key", context)
        .navigationHandler { destination: ChatDestination ->
            var url = ""
            if (destination is WebLinkDestination) {
                url = destination.url
            } else if (destination is AttachmentDestination) {
                url = destination.url
            }
            if (url.startsWith("https://your.domain.com")) {
                Toast.makeText(context, "Custom url handling: $url", Toast.LENGTH_SHORT).show()
                // handle/change/update url
                // open your webview, system browser or your own activity
                // and return true to override default behaviour
                true
            } else {
                false
            }
        }
        .build()
                    

Another example is opening a custom camera interface:


Chat chat = new Chat.Builder("api-key", context)
        .navigationHandler(destination -> {
            if (destination instanceof CameraDestination) {
                //open custom camera activity
                return true;
            } else {
                return false;
            }
        })
       .build();
                    

val chat = Chat.Builder("api-key", context)
        .navigationHandler { destination: ChatDestination? ->
            if (destination is CameraDestination) {
                //open custom camera activity
                true
            } else {
                false
            }
        }
        .build()
                    

The following 4 destinations are exposed by the Navigation Handler:

  • AppSettingsDestination opens app setting when required permissions are not granted

  • AttachmentDestination opens attachment activity when user click on attachment

  • CameraDestination opens camera when user makes photo or video to send it in channel

  • WebLinkDestination opens system web browser when user clicks on link