Upgrading from Pre-XDK Versions

The following upgrade instructions should help for developers upgrading from SDKs and UI Libraries Layer has shipped prior to the Layer XDK.

Update build.gradle Files

  • Upgrade the gradle plugin to at least version 3.1.0 and sync the project
  • The targetSdkVersion and compileSdkVersion should at least be 26
  • Change the Maven repository URL:
    maven { url "https://raw.githubusercontent.com/layerhq/Atlas-Android/master/releases/" }
    
    to
    maven { url "https://raw.githubusercontent.com/layerhq/Android-XDK/master/releases/" }
    
  • Change the dependency from
    compile 'com.layer.atlas:layer-atlas:0.4.21'
    
    to
    compile 'com.layer.xdk:xdk:4.0.0'
    

Update references to resources

  • Change any themes that extend from Theme.Atlas.Light to extend from Theme.XdkUi.Base.Light
  • If using any colors defined in Atlas’s color resources file, look for similar ones in res/xdk-ui-colors.xml. All XDK UI colors are now prefixed with xdk_ui_
  • If using any drawables defined in Atlas, look for similar ones in res/drawable. These are now mostly vector drawables and are prefixed with xdk_ui_

Dependency Management

Initialize a ServiceLocator instance with an application Context and LayerClient instance. Optionally define other objects as needed. It is recommeneded to use a singleton for this ServiceLocator instance.

This can also be bypassed if your app is using Dagger. Merely have your Component extend from or include the methods in XdkUiComponent. The same needs to be done for the XdkUiModule. Your Module should also include the XdkUiInternalModule.

Package and Name Changes

  • Change instances of com.layer.atlas.util.Log to com.layer.xdk.ui.util.Log
  • Change instances of com.layer.atlas.util.Util to com.layer.xdk.ui.util.Util
  • Change instances of com.layer.atlas.util.picasso.requesthandlers.MessagePartRequestHandler to com.layer.xdk.ui.message.image.cache.requesthandlers.MessagePartRequestHandler
  • Util.getVersion() is now Util.getXdkUiVersion()
  • Util.copyToClipboard() has been removed
  • Util.getDisplayName() has been deprecated in favor of using an IdentityFormatter instance
    • Names are normally formatted with the IdentityFormatter specified in the ServiceLocator (or your Dagger Component)
  • TextCellFactory and ThreePartImageUtils have been removed. Use LegacyMimeTypes for access to old mime types.
    • It is also recommended to add “*/*; role=root” and “*/*; role=preview” MIME types to the auto-downloaded types on LayerClient

Avatar Changes

  • AtlasAvatar has been removed. This should be replaced by an AvatarView with an optional PresenceView drawn over it. For example:
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical">
        <com.layer.xdk.ui.avatar.AvatarView
            android:id="@+id/avatar"
            android:layout_width="@dimen/xdk_ui_avatar_width"
            android:layout_height="@dimen/xdk_ui_avatar_height"
            android:layout_gravity="center_vertical" />
        <com.layer.xdk.ui.presence.PresenceView
            android:id="@+id/presence"
            android:layout_width="@dimen/xdk_ui_avatar_presence_height"
            android:layout_height="@dimen/xdk_ui_avatar_presence_height"
            android:layout_gravity="bottom|right" />
    </FrameLayout>
    
  • An ImageCacheWrapper and IdentityFormatter should be set on the AvatarView. These can be added using databinding:
    <com.layer.xdk.ui.avatar.AvatarView
        android:id="@+id/avatar"
        android:layout_width="@dimen/xdk_ui_avatar_width"
        android:layout_height="@dimen/xdk_ui_avatar_height"
        app:identityFormatter="@{viewModel.identityFormatter}"
        app:imageCacheWrapper="@{viewModel.imageCacheWrapper}">
    
    Or by java setters:
    avatarView.setIdentityFormatter(identityFormatter);
    avatarView.setImageCacheWrapper(imageCacheWrapper);
    
  • When setting the participants on the avatar view, also set the participants on the PresenceView the same way:
    presenceView.setParticipants(participantSet);
    
    • Participants on both the PresenceView and the AvatarView can also be set via databinding by supplying an app:participants="@{viewModel.participants}" attribute in the XML element.

New Identity List

  • Lists of Identities should now use an IdentityItemsListView driven by a IdentityItemsListViewModel. Define the view in your layout:
    <com.layer.xdk.ui.identity.IdentityItemsListView
        android:id="@+id/participants"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:adapter="@{viewModel.getAdapter}"
        app:itemHeight="@dimen/xdk_ui_item_height_medium"
        />
    
  • This uses databinding to set the adapter (app:adapter="@{viewModel.getAdapter}") by adding the following variable:
    <data>
        <variable
            name="viewModel"
            type="com.layer.xdk.ui.identity.IdentityItemsListViewModel"/>
    </data>
    
    Alternatively you can set the adapter without databinding via IdentityItemsListView:
    identityItemsListView.setAdapter(viewModel.getAdapter());
    
  • An IdentityItemsListViewModel is then created from the XdkUiComponent instance via identityItemsListViewModel(). You can then set a list of identities on it:
    identityItemsListViewModel.useIdentities(participantList);
    
    or define a query to populate it:
    identityItemsListViewModel.useQuery(predicate, sortDescripter);
    
  • A click listener can be set on this view by calling:
    identityItemsListViewModel.setItemClickListener(listener);
    

Removal of AtlasConversationsRecyclerView

  • This RecyclerView has been replaced by a ConversationItemsListView driven by a ConversationItemsListViewModel. Define the view in your layout:
    <com.layer.xdk.ui.conversation.ConversationItemsListView
        android:id="@+id/conversations_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:itemHeight="@dimen/xdk_ui_item_height_large"
        app:adapter="@{viewModel.conversationItemsAdapter}"/>
    
  • This uses databinding to set the adapter (app:adapter="@{viewModel.conversationItemsAdapter}") by adding the following variable:
    <data>
        <variable
            name="viewModel"
            type="com.layer.xdk.ui.conversation.ConversationItemsListViewModel"/>
    </data>
    
    Alternatively you can set the adapter without databinding via ConversationItemsListView:
    conversationItemsListView.setAdapter(viewModel.getConversationItemsAdapter());
    
  • A ConversationItemsListViewModel is then created from the XdkUiComponent instance via conversationItemsListViewModel().
  • Convert calls from AtlasConversationsRecyclerView.setInitialHistoricMessagesToFetch() to ConversationItemsListViewModel.setInitialHistoricMessagesToFetch()
  • You can either use the default query:
    viewModel.useDefaultQuery();
    
    or define your own:
    viewModel.useQuery(predicate, sortDescriptor);
    
  • Click listeners can be set via:
    viewModel.setItemClickListener(clickListener);
    viewModel.setItemLongClickListener(longClickListener);
    
    • Note that existing AtlasConversationsAdapter.OnConversationClickListener() functionality should be moved to the long click listener.
  • It is no longer necessary to call an onDestroy() method on the ConversationItemsListView. Calls to AtlasConversationsRecyclerView can be safely deleted.

Removal of AtlasMessagesRecyclerView

  • The AtlasMessagesRecyclerView has been replaced by a ConversationView driven by a ConversationViewModel. This also includes a ComposeBar and a SwipeRefreshLayout. Define the view in your layout:
    <com.layer.xdk.ui.conversation.ConversationView
        android:id="@+id/conversation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:conversation="@{viewModel.conversation}"
        app:layerClient="@{viewModel.layerClient}"
        app:messageItemsListViewModel="@{viewModel.messageItemsListViewModel}"/>
    
  • This uses databinding to set a few fields (conversation, layerClient and messageItemsListViewModel) by adding the following variable:
    <data>
        <variable
            name="viewModel"
            type="com.layer.xdk.ui.conversation.ConversationViewModel"/>
    </data>
    
    Alternatively you can set these fields without databinding via ConversationView:
    ConversationView.setConversation(conversationView, 
            conversation,
            viewModel.getLayerClient(),
            viewModel.getMessageItemsListViewModel());
    
  • A ConversationViewModel is then created from the XdkUiComponent instance via conversationViewModel().
  • AtlasMessagesRecyclerView.setOnMessageSwipeListener() calls should be converted to long click calls using ConversationViewModel.getMessageItemsListViewModel().setItemLongClickListener()
  • AtlasHistoricMessagesFetchLayout.setHistoricMessagesPerFetch() calls should be converted to ConversationView.getMessageItemListView().setNumberOfItemsPerSync()
  • It is no longer necessary to call an onDestroy() method on the ConversationView. Calls to AtlasMessagesRecyclerView can be safely deleted.
  • The TypingIndicatorLayout can be accessed via ConversationView.getTypingIndicator() so the layout or mode can be changed. The default mode is to show an Atlas-like indicator along with a text indicator.
  • All default Atlas CellFactory objects are now MessageModels and are automatically registered.

Removal of CellFactory

Any custom class that extends CellFactory should be converted to a MessageModel and registered with the MessageModelManager. For more information on how to create a custom MessageModel, see UI Components

Removal of AtlasTypingIndicator

The AtlasTypingIndicator has been replaced by TypingIndicatorLayout. It is normally not needed to include this in your layout as it is included in a ConversationView.

Removal of AtlasAddressBar

The AtlasAddressBar has been removed as it is no longer the recommended way of selecting participants for a new conversation. An IdentityItemsListView should be used instead.

If the AtlasAddressBar concept is still desired, you can look at the AddressBar in XDK-Messenger.

Removal of AtlasHistoricMessagesFetchLayout

The AtlasHistoricMessagesFetchLayout's functionality is incorporated in the new ConversationView

Change AtlasMessageComposer to ComposeBar

The ComposeBar no longer requires an init() call. It also doesn’t require a layout declaration if a ConversationView is being used. Merely fetch the instance using ConversationView.getComposeBar().

  • Set a new text sender by calling:

    composeBar.setTextSender(new RichTextSender(context, layerClient);
    
  • Change the namespace of the CameraSender to com.layer.xdk.ui.message.sender.CameraSender. Update the signature to the new format. Example:

    new CameraSender(R.string.xdk_ui_attachment_menu_camera,
            R.drawable.ic_photo_camera_black_24dp, activity, layerClient,
            getApplicationContext().getPackageName() + ".file_provider");
    
  • Change the namespace of the GallerySender to com.layer.xdk.ui.message.sender.GallerySender. Update the signature to the new format. Example:

    new GallerySender(R.string.xdk_ui_attachment_menu_gallery,
            R.drawable.ic_photo_black_24dp, activity, layerClient);
    
  • Replace LocationSender with CurrentLocationSender. Example:

    new CurrentLocationSender(R.string.xdk_ui_attachment_menu_current_location,
            R.drawable.ic_place_black_24dp, activity, layerClient,
            identityFormatter);
    

Extension of MessageSender or AttachmentSender

If any custom message senders have been implemented, please review the new classes for method signature changes.

Core API Reference Changelog