LogoLogo
Useful links
  • Home
  • Product guides
  • API
  • SDKs
  • Overview
  • First steps
  • ANDROID
    • Getting Started with the SDK
    • Standalone Modules
      • Document Detector
        • Release Notes
        • Current Version
        • Requirements
        • Gradle Dependencies
        • Gradle Source Code
        • Setting up the SDK
          • Setting properties
          • Capture Stages
          • Messages Settings
          • Customization
          • Security Settings
          • Detection Steps
          • Upload Mode
          • Advanced Settings
            • Proxy configuration
            • Preview configuration
        • Start Document Detection
        • Source Code
        • Google security form
        • Reduce SDKs size
        • SDKs response
        • References
        • FAQ
      • Face Liveness
        • Release Notes
        • Current Version
        • Requirements
        • Gradle Dependencies
        • Gradle Source Code
        • SDK Lifecycle
        • Building the SDK
        • Start Liveness Verification
        • Source Code
        • References
        • Advanced Features
        • FAQ
      • Face Authenticator
        • Release Notes
      • Smart Auth
        • Release Notes
        • Current Version
        • Requirements
        • Gradle Dependencies
        • Gradle Source Code
        • Permissions
        • SDK Lifecycle
        • Building the SDK
        • Start Smart Authentication
        • Source Code
        • References
        • FAQ
      • Face Liveness (deprecated)
        • Release Notes
  • iOS
    • Getting Started with the SDK
    • Standalone Modules
      • Document Detector
        • Release Notes
        • Current Version
        • Requirements
        • Installing the SDK
        • Setting up the SDK
          • Setting properties
          • Messages Settings
          • Customization
          • Detection Steps
          • Upload Mode
          • Advanced Settings
            • Proxy configuration
            • Preview configuration
        • Start Document Detection
        • References
        • FAQ
      • Face Liveness
        • Release Notes
        • Installation
        • Current Version
        • Requirements
        • SDK Lifecycle
        • Building the SDK
        • Start Liveness Verification
        • Source Code
        • References
        • FAQ
      • Face Authenticator
        • Release Notes
        • Installation
        • Current Version
        • Requirements
        • Building the SDK
        • Start the SDK
        • References
        • FAQ
      • Smart Auth
        • Release Notes
        • Installation
        • Current Version
        • Requirements
        • SDK Lifecycle
        • Building the SDK
        • Start Smart Authentication
        • Source Code
        • References
        • FAQ
      • Face Liveness (deprecated)
        • Release Notes
  • REACT NATIVE
    • Standalone Modules
      • Document Detector
        • Release Notes
        • Current Version
        • Requirements
        • Installation
        • Hooks
        • Start Document Verification
        • Source Code
        • TypeScript References
        • Customizing Style
        • FAQ
      • Face Liveness
        • Release Notes
        • Current Version
        • Requirements
        • Installation
        • Hooks
        • Start Liveness Verification
        • Source Code
        • TypeScript References
        • FAQ
      • Face Authenticator
        • Release Notes
        • Current Version
        • Requirements
        • Installation
        • Hooks
        • Start Authentication Verification
        • Source Code
        • TypeScript References
        • FAQ
      • Smart Auth
        • Getting started
        • Release notes
        • Using Native Modules
          • Requirements
          • Gradle Source Code
          • Podfile Source Code
          • Native Module Android
          • Native Module iOS
          • Import Native Modules
          • Source Code
          • TypeScript References
          • FAQ
        • Using Expo Modules
          • Requirements
          • Create Local Expo Module
          • Gradle Source Code
          • Podspec Source Code
          • Native Module Android
          • Native Module iOS
          • Import Expo Modules
          • Source Code
          • TypeScript References
          • FAQ
  • WEB (JAVASCRIPT)
    • Standalone Modules
      • Document Detector
        • Getting started
        • SDK builder options
          • Analytics
          • Appearance
          • Messages
        • SDK methods
        • Event listeners
        • Customization
        • Release notes
      • Face Liveness
        • Customization
        • Release notes
      • Face Authenticator
        • Customization
        • Release notes
      • Smart Auth
        • SDK errors
        • Customization
        • Release notes
LogoLogo

2025 © Caf. - All rights reserved

On this page
  • Custom layout creation
  • Step-by-step
  • Variables and methods used in layout
  • Methods
  • State variables
  • Visibility variables
  • ValidationFailure
  • Using layout in Builder
  • Builder method
  • Using the methods
  • Custom style creation
  • Customization of masks
  • Default templates
  1. ANDROID
  2. Standalone Modules
  3. Document Detector
  4. Setting up the SDK

Customization

Learn how to customize our SDK and make it look like your app.

Last updated 2 months ago

Custom layout creation

To create a new layout we recommend that you use the from the SDKs and make the desired changes.

Step-by-step

  1. Declare the dependency on CameraView in your app-level gradle file.

// CameraX core library using the camera2 implementation
implementation "androidx.camera:camera-view:1.3.4"

2. Create a layout file in your project's layout directory using the CAF template.

3. Create your views, and parameterize the visibility and call methods of the ViewModel of each corresponding SDK according to the following tables. Example:

<layout>
...
    <androidx.camera.view.PreviewView
        android:id="@id/cameraImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="@{viewModel.cameraVisibility ? View.VISIBLE : View.GONE}"
    />
    ...
</layout>

Variables and methods used in layout

All the methods and variables described below are accessed from the SDKViewModel class.

Methods

Method
Description
Return
SDK

takePhoto()

Responsible for initiating image capture in MANUAL mode

Void

DocumentDetector, PassiveFaceLiveness

close()

Responsible for closing the SDK.

Void

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

switchCamera()

Responsible for reversing the camera.

Void

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

State variables

The Layout used in the SDK is composed of several state variables, these variables are responsible for identifying the state that the SDK is in at each moment of its execution:

Variable
Description
Type
SDK

loadingStatus

Indicates the 'loading' state

Boolean

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

readyToCaptureStatus

Indicates that the SDK is ready to capture, after performing all validations for sensors, framing, face, etc.

Boolean

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

stepDoneSuccessfullyStatus

Indicates that the capture step ended successfully

Boolean

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

validationFailureStatus

Indicates if there are any faulty sensor checks, quality, framing, face distance, etc.

Boolean

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

validationFailureId

Indicates what type of error has occurred. See the table below

ValidationFailure

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

captureModeStatus

Indicates the capture mode enabled. May vary between AUTOMATIC and MANUAL

CaptureMode

DocumentDetector, PassiveFaceLiveness

maskStatus

Indicates the status of the mask. Can range from NORMAL, SUCCESS to ERROR

Mask

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

maskLayout

Responsible for returning the Drawable Resource Id used to define the mask.

Integer

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

previousStepName

Name of the previous step that was performed. If not, the value will be null. Example: Back of ID.

String

DocumentDetector v7.x or below

Visibility variables

Variable
Description
Type
SDK

popUpVisibility

Indicates the visibility of the step initialization popup

Boolean

DocumentDetector

manualCaptureButtonVisibility

Indicates visibility of the manual capture button

Boolean

DocumentDetector, PassiveFaceLiveness

switchCameraButtonVisibility

Indicates the visibility of the reverse camera button

Boolean

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

statusVisibility

Responsible for the visibility of the SDK status message.

Boolean

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

statusMessage

Returns the status message. Customize with MessageSettings

String

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

feedbackStatusMessage

Returns the status message. Customize with MessageSettings

String

DocumentDetector

cameraVisibility

Responsible for camera visibility.

Boolean

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

maskVisibility

Indicates mask visibility.

Boolean

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

switchButtonVisibility

Responsible for the visibility of the camera flip button.

This variable has been deprecated, we recommend using the switchCameraButtonVisibility variable.

Boolean

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

serverRequesting

Responsible for the visibility of the loading displayed by the SDK.

This variable has been deprecated, we recommend using the loadingStatus variable.

Boolean

DocumentDetector v7.x or below, PassiveFaceLiveness, FaceAuthenticator

buttonVisibility

Sets the visibility of the manual capture button.

This variable has been deprecated, use manualCaptureButtonVisibility.

Boolean

DocumentDetector v7.x or below, PassiveFaceLiveness

ValidationFailure

Each SDK contains a number of validation errors that can occur while running. These mostly generate the "error mask" state and prevent the capture from being performed:

Error
Description
SDK

SENSOR_LUMINOSITY_FAILURE

Brightness sensor. The environment is too dark

DocumentDetector, PassiveFaceLiveness

SENSOR_ORIENTATION_FAILURE

Orientation sensor. Device not in correct position

DocumentDetector, PassiveFaceLiveness

SENSOR_STABILITY_FAILURE

Stability sensor. The device is in motion

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

FRAMING_FAILURE

Document or face-framing

DocumentDetector, PassiveFaceLiveness, FaceAuthenticator

EYES_CLOSED_FAILURE

A face with closed eyes was identified

PassiveFaceLiveness, FaceAuthenticator

FACE_NOT_FOUND

No face was found

PassiveFaceLiveness, FaceAuthenticator

FACE_TOO_FAR

Face too far away.

PassiveFaceLiveness, FaceAuthenticator

FACE_TOO_CLOSE

Very close face.

PassiveFaceLiveness, FaceAuthenticator

ANGULATION_X_FAILURE

Incorrect face angle on the X axis.

PassiveFaceLiveness

ANGULATION_Y_FAILURE

Incorrect face angle on the Y axis.

PassiveFaceLiveness

ANGULATION_Z_FAILURE

Incorrect face angle on the Z axis.

PassiveFaceLiveness

MULTIPLE_FACES_FAILURE

Multiple faces detected.

PassiveFaceLiveness, FaceAuthenticator

QUALITY_FAILURE

Quality of the document capture is too low.

DocumentDetector

LIVENESS_FAILURE

Error in the proof of life. It is a probable fraud attempt

PassiveFaceLiveness, FaceAuthenticator

TYPIFICATION_FAILURE

Document type or document side was not expected.

DocumentDetector

PASSPORT_COUNTRY_CODE_FAILURE

Passaport country code (or issuing code) is not allowed.

DocumentDetector

Using layout in Builder

After creating the desired files, create an object of type DocumentDetector. This object is for you to configure all your business rules for the SDK, including the interface customization attributes:

DocumentDetector mDocumentDetector = new DocumentDetector.Builder(String mobileToken)
    // see table below
    .build();

Builder method

Parameter
Required
Compatibility

.setLayout(@LayoutRes Integer layoutId)

Replaces the SDK's default layout. Create a file in your project's layout folder, copy the standard layout template corresponding to the SDK you are integrating and make the desired changes.

Latest versions

.setStyle(@StyleRes int styleResourceId)

Replaces the SDK's default style. In your project's styles.xml file, copy the default template and edit it.

Latest versions

.setMask(@DrawableRes Integer greenMask, @DrawableRes Integer whiteMask, @DrawableRes Integer redMask)

Replaces the masks for capturing a document or face: SUCCESS, NORMAL, and FAIL, in that order. If you use this option, use masks with the same detection area of the document and face, as this region is very important for the algorithm to capture.

DocumentDetector v7.x or below

.setMask(MaskType type)

Defines which group of masks predefined in the product will be used by the SDK:

  • MaskType.DEFAULT, with the dotted pattern in the document format or face;

  • MaskType.DETAILED, which displays an illustration of the requested document - CNH or RG - along with the dotted mask (only in DocumentDetector);

  • MaskType.NONE, which removes the mask entirely.

No. The default masks are used.

DocumentDetector v7.x or below

Using the methods

DocumentDetector mDocumentDetector = new DocumentDetector.Builder(String mobileToken)
    .setLayout(R.layout.customLayout)
    .setStyle(R.style.customStyle)
    .setMask(MaskType.DETAILED)
    .build();

Different uses .setMask() method

DocumentDetector mDocumentDetector = new DocumentDetector.Builder(String mobileToken)
    // Using Customized Masks
    .setMask(R.drawable.customGreenMask, R.drawable.customWhiteMask, R.drawable.customRedMask)
    // Using masks already offered by the SDK
    .setMask(MaskType.DETAILED)
    .build();

Custom style creation

Customization of masks

Default templates

Activity (setLayout)

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>
        <import type="android.view.View"/>

        <variable
            name="viewModel"
            type="com.combateafraude.documentdetector.controller.viewmodel.SDKViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:keepScreenOn="true">

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.1" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineEnd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.9" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineTop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.05" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.78" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineBottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.97" />

        <androidx.camera.view.PreviewView
            android:id="@id/cameraImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="@{viewModel.cameraVisibility ? View.VISIBLE : View.GONE}"
            />

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@{viewModel.previewBitMap}"
            android:visibility="@{viewModel.previewVisibility ? View.VISIBLE : View.GONE}">
        </ImageView>

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:contentDescription="@string/photo_mask_caf"
            android:scaleType="fitXY"
            android:visibility="@{viewModel.maskVisibility ? View.VISIBLE : View.GONE}"
            android:src="@{context.getDrawable(viewModel.maskLayout)}" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:adjustViewBounds="true"
            android:contentDescription="@string/close_caf"
            android:onClick="@{() -> viewModel.close()}"
            android:src="@drawable/ic_back_caf"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintTop_toTopOf="@id/guidelineTop" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:adjustViewBounds="true"
            android:contentDescription="@string/switch_caf"
            android:onClick="@{() -> viewModel.switchCamera()}"
            android:visibility="@{viewModel.switchCameraButtonVisibility ? View.VISIBLE : View.GONE}"
            android:src="@drawable/ic_camera_switch"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineTop" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:visibility="@{viewModel.manualCaptureButtonVisibility ? View.VISIBLE : View.GONE}"
            android:onClick="@{() -> viewModel.takePhoto()}"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineStatus"
            android:contentDescription="@string/take_picture"
            app:backgroundTint="?attr/colorPrimary"
            app:tint="#FFF"
            app:srcCompat="@drawable/ic_camera_caf"/>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:visibility="@{viewModel.statusVisibility ? View.VISIBLE : View.GONE}"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineStatus">

            <TextView
                android:id="@+id/statusMessage"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:background="@drawable/bg_radius_caf"
                android:gravity="center_horizontal"
                android:lineSpacingExtra="5sp"
                android:padding="8dp"
                android:layout_marginTop="10dp"
                android:textAlignment="center"
                android:textColor="#606060"
                android:textSize="15sp"
                android:textStyle="bold"
                android:text="@{viewModel.statusMessage}"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/triangle_caf"
                android:rotation="270"
                android:adjustViewBounds="true"
                android:contentDescription="@string/nothing_caf"
                app:layout_constraintEnd_toEndOf="@id/statusMessage"
                app:layout_constraintStart_toStartOf="@id/statusMessage"
                app:layout_constraintTop_toTopOf="@id/statusMessage"
                app:layout_constraintBottom_toTopOf="@id/statusMessage" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <TextView
            android:id="@+id/tvCurrentStepName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@id/tvPreviousStepName"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            android:layout_marginBottom="5dp"
            android:textSize="18sp"
            android:textColor="#ffffff"
            android:letterSpacing="0.06"
            android:text="@{viewModel.currentStepName}"
            android:gravity="center_horizontal" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:visibility="@{viewModel.currentStepDone ? View.VISIBLE : View.GONE}"
            android:contentDescription="@string/check_caf"
            app:layout_constraintTop_toTopOf="@id/tvCurrentStepName"
            app:layout_constraintBottom_toBottomOf="@id/tvCurrentStepName"
            app:layout_constraintEnd_toStartOf="@id/tvCurrentStepName"
            android:layout_marginEnd="8dp"
            android:src="@drawable/ic_check_caf" />

        <TextView
            android:id="@+id/tvPreviousStepName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottom"
            android:textSize="16sp"
            android:textColor="#66FFFFFF"
            android:letterSpacing="0.06"
            android:text="@{viewModel.previousStepName}"
            android:gravity="center_horizontal" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:visibility="@{viewModel.previousStepDone ? View.VISIBLE : View.GONE}"
            android:contentDescription="@string/check_caf"
            app:layout_constraintTop_toTopOf="@id/tvPreviousStepName"
            app:layout_constraintBottom_toBottomOf="@id/tvPreviousStepName"
            app:layout_constraintEnd_toStartOf="@id/tvPreviousStepName"
            android:layout_marginEnd="8dp"
            android:alpha="0.4"
            android:src="@drawable/ic_check_caf" />

        <ProgressBar
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:indeterminate="true"
            android:indeterminateTint="?attr/colorPrimary"
            android:indeterminateTintMode="src_atop"
            android:visibility="@{viewModel.loadingStatus ? View.VISIBLE : View.GONE}"
            app:layout_constraintVertical_bias="0.45"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottom"
            app:layout_constraintTop_toTopOf="@id/guidelineTop"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Styles (setStyle)

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="windowProperties" parent="Theme.MaterialComponents.Light">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowActivityTransitions">true</item>
        <item name="android:colorControlActivated">#606060</item>
    </style>

    <style name="defaultStyle" parent="windowProperties">
        <item name="colorPrimary">#4CD964</item>
    </style>

    <style name="defaultButtonStyle" parent="Widget.MaterialComponents.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#FFFFFF</item>
        <item name="android:textSize">18sp</item>
        <item name="android:fontFamily">sans-serif</item>
        <item name="android:textAllCaps">false</item>
    </style>

    <style name="transparentButton" parent="Widget.MaterialComponents.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#323232</item>
        <item name="android:textSize">18sp</item>
        <item name="android:textStyle">normal</item>
        <item name="android:fontFamily">@font/roboto</item>
        <item name="android:textAllCaps">false</item>
        <item name="android:background">#00FFFFFF</item>
    </style>

    <style name="textPreview" parent="windowProperties">
        <item name="android:textColor">#323232</item>
    </style>

</resources>

Mask (setMask)

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="375dp"
    android:height="667dp"
    android:viewportWidth="375"
    android:viewportHeight="667">
  <path
      android:pathData="M375,0V667H0V0H375ZM341,85H35V516H341V85Z"
      android:strokeAlpha="0.35"
      android:fillColor="#000000"
      android:fillType="evenOdd"
      android:fillAlpha="0.35"/>
  <!-- 
      The color of the mask can be changed by the android:fillColor attribute of the element below.
      The default colors are: #22CB7B (green), #E74C3C (red), #ffffff (white)
  -->
  <path
      android:pathData="--image-byte-array-"
      android:fillColor="#22CB7B" 
      android:fillType="evenOdd"/>
</vector>

Activity (setLayout)

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="android.view.View" />

        <import type="com.combateafraude.documentdetector.R" />

        <variable
            name="viewModel"
            type="com.combateafraude.documentdetector.controller.viewmodel.SDKViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/caf_black"
        android:keepScreenOn="true">

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.1" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineEnd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.9" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineTop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.05" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineBottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.97" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:elevation="1dp"
            app:layout_constraintEnd_toEndOf="@id/frameCameraPreview"
            app:layout_constraintStart_toStartOf="@id/frameCameraPreview"
            app:layout_constraintTop_toTopOf="@id/frameCameraPreview">

            <ImageView
                android:id="@+id/closeImage"
                android:layout_width="32dp"
                android:layout_height="32dp"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                android:adjustViewBounds="true"
                android:contentDescription="@string/close_caf"
                android:onClick="@{() -> viewModel.close()}"
                android:src="@drawable/close_capture"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/tvCurrentStepName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:gravity="center_horizontal"
                android:lineSpacingExtra="5sp"
                android:paddingHorizontal="12dp"
                android:paddingVertical="4dp"
                android:text="@{viewModel.stepName}"
                android:textColor="@color/caf_white"
                android:textSize="16sp"
                android:textStyle="bold"
                android:visibility="@{(viewModel.stepNameVisibility &amp;&amp; viewModel.stepName.length() > 0) ? View.VISIBLE : View.INVISIBLE}"
                app:cafBackgroundColor="@{R.color.mask_color_black_background}"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:text="CNH" />
        </androidx.constraintlayout.widget.ConstraintLayout>

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineTopCameraPreview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent=".06" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineBottomCameraPreview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent=".94" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStartCameraPreview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent=".04" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineEndCameraPreview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent=".96" />

        <FrameLayout
            android:id="@+id/frameCameraPreview"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottomCameraPreview"
            app:layout_constraintEnd_toEndOf="@id/guidelineEndCameraPreview"
            app:layout_constraintStart_toStartOf="@id/guidelineStartCameraPreview"
            app:layout_constraintTop_toTopOf="@id/guidelineTopCameraPreview">

            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:elevation="0dp"
                app:cardCornerRadius="16dp">

                <androidx.camera.view.PreviewView
                    android:id="@id/cameraImageView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:visibility="@{viewModel.cameraVisibility ? View.VISIBLE : View.GONE}" />

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="80dp"
                    android:importantForAccessibility="no"
                    android:src="@drawable/preview_camera_gradient" />

                <ImageView
                    android:id="@+id/previewBitmap"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:importantForAccessibility="no"
                    android:src="@{viewModel.previewBitMap}"
                    android:visibility="@{viewModel.previewVisibility ? View.VISIBLE : View.GONE}" />
            </androidx.cardview.widget.CardView>
        </FrameLayout>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/maskInfoContainer"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottom"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintTop_toTopOf="@id/guidelineTop">

            <ImageView
                android:id="@+id/maskImage"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:adjustViewBounds="true"
                android:contentDescription="@string/photo_mask_caf"
                android:src="@{viewModel.feedbackImage}"
                android:visibility="@{viewModel.feedbackImageVisibility ? View.VISIBLE : View.INVISIBLE}"
                app:cafBackgroundColor="@{viewModel.feedbackStatusBackground}"
                app:layout_constraintBottom_toBottomOf="@id/maskInfoContainer"
                app:layout_constraintEnd_toEndOf="@id/maskInfoContainer"
                app:layout_constraintStart_toStartOf="@id/maskInfoContainer"
                app:layout_constraintTop_toTopOf="@id/maskInfoContainer"
                app:layout_constraintVertical_bias="0.40"
                tools:src="@drawable/center_image" />

            <TextView
                android:id="@+id/statusMessage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:layout_marginEnd="8dp"
                android:gravity="center_horizontal"
                android:lineSpacingExtra="5sp"
                android:paddingHorizontal="12dp"
                android:paddingVertical="4dp"
                android:text="@{viewModel.feedbackStatusMessage}"
                android:textAlignment="center"
                android:textColor="#FFFFFF"
                android:textSize="15sp"
                android:textStyle="bold"
                android:visibility="@{viewModel.feedbackStatusMessage.length() > 0 ? View.VISIBLE : View.GONE}"
                app:cafBackgroundColor="@{viewModel.feedbackStatusBackground}"
                app:layout_constraintEnd_toEndOf="@id/maskInfoContainer"
                app:layout_constraintStart_toStartOf="@id/maskInfoContainer"
                app:layout_constraintTop_toBottomOf="@id/maskImage"
                tools:background="@drawable/bg_radius_caf" />
        </androidx.constraintlayout.widget.ConstraintLayout>

        <ImageButton
            android:id="@+id/floatingActionButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:background="@null"
            android:contentDescription="@string/take_picture"
            android:onClick="@{() -> viewModel.takePhoto()}"
            android:src="@drawable/ic_shutter_caf"
            android:visibility="@{viewModel.manualCaptureButtonVisibility ? View.VISIBLE : View.GONE}"
            app:layout_constraintBottom_toBottomOf="@+id/frameCameraPreview"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintStart_toStartOf="@id/guidelineStart" />

        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_margin="16dp"
            android:indeterminate="true"
            android:indeterminateTint="@color/caf_white"
            android:indeterminateTintMode="src_atop"
            android:padding="8dp"
            android:visibility="@{viewModel.loadingStatus ? View.VISIBLE : View.GONE}"
            app:cafBackgroundColor="@{viewModel.feedbackStatusBackground}"
            app:layout_constraintBottom_toBottomOf="@id/maskInfoContainer"
            app:layout_constraintEnd_toEndOf="@id/maskInfoContainer"
            app:layout_constraintStart_toStartOf="@id/maskInfoContainer"
            app:layout_constraintTop_toTopOf="@id/maskInfoContainer"
            app:layout_constraintVertical_bias="0.395" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Style (setStyle)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="cafDefaultStyle" parent="cafWindowProperties">
        <item name="colorPrimary">#34D690</item>
    </style>

    <style name="cafDefaultButtonStyle" parent="Widget.AppCompat.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#FFFFFF</item>
        <item name="android:textSize">18sp</item>
        <item name="android:fontFamily">sans-serif</item>
        <item name="android:textAllCaps">false</item>
        <item name="backgroundTint">?attr/colorPrimary</item>
    </style>

    <style name="cafTransparentButtonStyle" parent="Widget.MaterialComponents.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#323232</item>
        <item name="android:textSize">18sp</item>
        <item name="android:textStyle">normal</item>
        <item name="android:fontFamily">@font/roboto</item>
        <item name="android:textAllCaps">false</item>
        <item name="android:background">#00FFFFFF</item>
    </style>

    <style name="cafTextPreviewStyle" parent="cafWindowProperties">
        <item name="android:textColor">#323232</item>
    </style>

    <style name="cafDefaultUploadStyle" parent="cafWindowProperties">
        <item name="android:background">?attr/colorPrimary</item>
    </style>

    <style name="cafDefaultPreviewStyle" parent="cafWindowProperties">
        <item name="android:background">?attr/colorPrimary</item>
    </style>
</resources>

Activity (setLayout)

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <import type="android.view.View"/>

        <variable
            name="viewModel"
            type="com.combateafraude.passivefaceliveness.controller.viewmodel.SDKViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:keepScreenOn="true">

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.1" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineEnd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.9" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineTop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.05" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.7" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineBottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.97" />


        <androidx.camera.view.PreviewView
            android:id="@id/cameraImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="@{viewModel.cameraVisibility ? View.VISIBLE : View.GONE}"
            >

        </androidx.camera.view.PreviewView>

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@{viewModel.previewBitMap}"
            android:visibility="@{viewModel.previewVisibility ? View.VISIBLE : View.GONE}">
        </ImageView>

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:contentDescription="@string/photo_mask_caf"
            android:scaleType="fitXY"
            android:src="@{context.getDrawable(viewModel.maskLayout)}"
            android:visibility="@{viewModel.maskVisibility ? View.VISIBLE : View.GONE}" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:adjustViewBounds="true"
            android:contentDescription="@string/close_caf"
            android:onClick="@{() -> viewModel.close()}"
            android:src="@drawable/ic_back_caf"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintTop_toTopOf="@id/guidelineTop" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:adjustViewBounds="true"
            android:contentDescription="@string/switch_camera"
            android:onClick="@{() -> viewModel.switchCamera()}"
            android:src="@drawable/ic_camera_switch"
            android:visibility="@{viewModel.switchCameraButtonVisibility ? View.VISIBLE : View.GONE}"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineTop" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:visibility="@{viewModel.manualCaptureButtonVisibility ? View.VISIBLE : View.GONE}"
            android:onClick="@{() -> viewModel.takePhoto()}"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineStatus"
            android:contentDescription="@string/take_picture"
            app:backgroundTint="?attr/colorPrimary"
            app:tint="#FFF"
            app:srcCompat="@drawable/ic_camera_caf"/>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:visibility="@{viewModel.statusVisibility ? View.VISIBLE : View.GONE}"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineStatus">

            <TextView
                android:id="@+id/statusMessage"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:background="@drawable/bg_radius_caf"
                android:gravity="center_horizontal"
                android:lineSpacingExtra="7sp"
                android:padding="10dp"
                android:layout_marginTop="10dp"
                android:textAlignment="center"
                android:textColor="#606060"
                android:textSize="15sp"
                android:textStyle="bold"
                android:text="@{viewModel.statusMessage}"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/triangle_caf"
                android:rotation="270"
                android:adjustViewBounds="true"
                android:contentDescription="@string/nothing_caf"
                app:layout_constraintEnd_toEndOf="@id/statusMessage"
                app:layout_constraintStart_toStartOf="@id/statusMessage"
                app:layout_constraintTop_toTopOf="@id/statusMessage"
                app:layout_constraintBottom_toTopOf="@id/statusMessage" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <TextView
            android:id="@+id/tvCurrentStepName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@id/tvPreviousStepName"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            android:layout_marginBottom="5dp"
            android:textSize="18sp"
            android:textColor="#ffffff"
            android:letterSpacing="0.06"
            android:text="@{viewModel.currentStepName}"
            android:gravity="center_horizontal" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:visibility="@{viewModel.currentStepDone ? View.VISIBLE : View.GONE}"
            android:contentDescription="@string/check_caf"
            app:layout_constraintTop_toTopOf="@id/tvCurrentStepName"
            app:layout_constraintBottom_toBottomOf="@id/tvCurrentStepName"
            app:layout_constraintEnd_toStartOf="@id/tvCurrentStepName"
            android:layout_marginEnd="8dp"
            android:src="@drawable/ic_check_caf" />

        <TextView
            android:id="@+id/tvPreviousStepName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottom"
            android:textSize="16sp"
            android:textColor="#66FFFFFF"
            android:letterSpacing="0.06"
            android:text="@{viewModel.previousStepName}"
            android:gravity="center_horizontal" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:visibility="@{viewModel.previousStepDone ? View.VISIBLE : View.GONE}"
            android:contentDescription="@string/check_caf"
            app:layout_constraintTop_toTopOf="@id/tvPreviousStepName"
            app:layout_constraintBottom_toBottomOf="@id/tvPreviousStepName"
            app:layout_constraintEnd_toStartOf="@id/tvPreviousStepName"
            android:layout_marginEnd="8dp"
            android:alpha="0.4"
            android:src="@drawable/ic_check_caf" />

        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:indeterminate="true"
            android:indeterminateTint="?attr/colorPrimary"
            android:indeterminateTintMode="src_atop"
            android:visibility="@{viewModel.loadingStatus ? View.VISIBLE : View.GONE}"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottom"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintTop_toTopOf="@id/guidelineTop"
            app:layout_constraintVertical_bias="0.45" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Style (setStyle)

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="windowProperties" parent="Theme.MaterialComponents.Light">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowActivityTransitions">true</item>
        <item name="android:colorControlActivated">#606060</item>
    </style>

    <style name="defaultStyle" parent="windowProperties">
        <item name="colorPrimary">#4CD964</item>
    </style>

    <style name="defaultButtonStyle" parent="Widget.MaterialComponents.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#FFFFFF</item>
        <item name="android:textSize">18sp</item>
        <item name="android:fontFamily">sans-serif</item>
        <item name="android:textAllCaps">false</item>
    </style>

    <style name="transparentButton" parent="Widget.MaterialComponents.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#323232</item>
        <item name="android:textSize">18sp</item>
        <item name="android:textStyle">normal</item>
        <item name="android:fontFamily">@font/roboto</item>
        <item name="android:textAllCaps">false</item>
        <item name="android:background">#00FFFFFF</item>
    </style>

    <style name="textPreview" parent="windowProperties">
        <item name="android:textColor">#323232</item>
    </style>

</resources>

Mask (setMask)

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="375dp"
    android:height="667dp"
    android:viewportWidth="375"
    android:viewportHeight="667">
  <path
      android:pathData="M375,0V667H0V0H375ZM187.5,130C84.91,130 76,208 76,282.5C76,357 131.133,455 187.5,455C243.867,455 299,357 299,282.5C299,208 290.09,130 187.5,130Z"
      android:strokeAlpha="0.35"
      android:fillColor="#000000"
      android:fillType="evenOdd"
      android:fillAlpha="0.35"/>
  <!-- 
      The color of the mask can be changed by the android:fillColor attribute of the element below.
      The default colors are: #22CB7B (green), #E74C3C (red), #ffffff (white)
  -->
  <path
      android:pathData="--image-byte-array-"
      android:fillColor="#22CB7B"
      android:fillType="evenOdd"/>
</vector>

Activity (setLayout)

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>
        <import type="android.view.View"/>

        <variable
            name="viewModel"
            type="com.combateafraude.faceauthenticator.controller.viewmodel.SDKViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:keepScreenOn="true">

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.1" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineEnd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.9" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineTop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.05" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineStatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.7" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineBottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.97" />

        <androidx.camera.view.PreviewView
            android:id="@id/cameraImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:contentDescription="@string/photo_mask_caf"
            android:scaleType="fitXY"
            android:src="@{context.getDrawable(viewModel.maskLayout)}" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:adjustViewBounds="true"
            android:contentDescription="@string/close_caf"
            android:onClick="@{() -> viewModel.close()}"
            android:src="@drawable/ic_back_caf"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintTop_toTopOf="@id/guidelineTop" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:adjustViewBounds="true"
            android:contentDescription="@string/switch_camera"
            android:onClick="@{() -> viewModel.switchCamera()}"
            android:src="@drawable/ic_camera_switch"
            android:visibility="@{viewModel.switchCameraButtonVisibility ? View.VISIBLE : View.GONE}"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineTop" />


        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:visibility="@{viewModel.manualCaptureButtonVisibility ? View.VISIBLE : View.GONE}"
            android:onClick="@{() -> viewModel.takePhoto()}"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineStatus"
            android:contentDescription="@string/take_picture"
            app:backgroundTint="?attr/colorPrimary"
            app:tint="#FFF"
            app:srcCompat="@drawable/ic_camera_caf"/>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:visibility="@{viewModel.statusVisibility ? View.VISIBLE : View.GONE}"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintTop_toTopOf="@id/guidelineStatus">

            <TextView
                android:id="@+id/statusMessage"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:background="@drawable/bg_radius_caf"
                android:gravity="center_horizontal"
                android:lineSpacingExtra="7sp"
                android:padding="10dp"
                android:layout_marginTop="10dp"
                android:textAlignment="center"
                android:textColor="#606060"
                android:textSize="15sp"
                android:textStyle="bold"
                android:text="@{viewModel.statusMessage}"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/triangle_caf"
                android:rotation="270"
                android:adjustViewBounds="true"
                android:contentDescription="@string/nothing_caf"
                app:layout_constraintEnd_toEndOf="@id/statusMessage"
                app:layout_constraintStart_toStartOf="@id/statusMessage"
                app:layout_constraintTop_toTopOf="@id/statusMessage"
                app:layout_constraintBottom_toTopOf="@id/statusMessage" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <TextView
            android:id="@+id/tvCurrentStepName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@id/tvPreviousStepName"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            android:layout_marginBottom="5dp"
            android:textSize="18sp"
            android:textColor="#ffffff"
            android:letterSpacing="0.06"
            android:text="@{viewModel.currentStepName}"
            android:gravity="center_horizontal" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:visibility="@{viewModel.currentStepDone ? View.VISIBLE : View.GONE}"
            android:contentDescription="@string/check_caf"
            app:layout_constraintTop_toTopOf="@id/tvCurrentStepName"
            app:layout_constraintBottom_toBottomOf="@id/tvCurrentStepName"
            app:layout_constraintEnd_toStartOf="@id/tvCurrentStepName"
            android:layout_marginEnd="8dp"
            android:src="@drawable/ic_check_caf" />

        <TextView
            android:id="@+id/tvPreviousStepName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottom"
            android:textSize="16sp"
            android:textColor="#66FFFFFF"
            android:letterSpacing="0.06"
            android:text="@{viewModel.previousStepName}"
            android:gravity="center_horizontal" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:visibility="@{viewModel.previousStepDone ? View.VISIBLE : View.GONE}"
            android:contentDescription="@string/check_caf"
            app:layout_constraintTop_toTopOf="@id/tvPreviousStepName"
            app:layout_constraintBottom_toBottomOf="@id/tvPreviousStepName"
            app:layout_constraintEnd_toStartOf="@id/tvPreviousStepName"
            android:layout_marginEnd="8dp"
            android:alpha="0.4"
            android:src="@drawable/ic_check_caf" />

        <ProgressBar
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:indeterminate="true"
            android:indeterminateTint="?attr/colorPrimary"
            android:indeterminateTintMode="src_atop"
            android:visibility="@{viewModel.loadingStatus ? View.VISIBLE : View.GONE}"
            app:layout_constraintVertical_bias="0.45"
            app:layout_constraintBottom_toBottomOf="@id/guidelineBottom"
            app:layout_constraintTop_toTopOf="@id/guidelineTop"
            app:layout_constraintStart_toStartOf="@id/guidelineStart"
            app:layout_constraintEnd_toEndOf="@id/guidelineEnd" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Style (setStyle)

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="windowProperties" parent="Theme.MaterialComponents.Light">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowActivityTransitions">true</item>
        <item name="android:colorControlActivated">#606060</item>
    </style>

    <style name="defaultStyle" parent="windowProperties">
        <item name="colorPrimary">#4CD964</item>
    </style>

    <style name="defaultButtonStyle" parent="Widget.MaterialComponents.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#FFFFFF</item>
        <item name="android:textSize">18sp</item>
        <item name="android:fontFamily">sans-serif</item>
        <item name="android:textAllCaps">false</item>
    </style>

    <style name="transparentButton" parent="Widget.MaterialComponents.Button">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">60dp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">#323232</item>
        <item name="android:textSize">18sp</item>
        <item name="android:textStyle">normal</item>
        <item name="android:fontFamily">@font/roboto</item>
        <item name="android:textAllCaps">false</item>
        <item name="android:background">#00FFFFFF</item>
    </style>

    <style name="textPreview" parent="windowProperties">
        <item name="android:textColor">#323232</item>
    </style>

</resources>

Mask (setMask)

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="375dp"
    android:height="667dp"
    android:viewportWidth="375"
    android:viewportHeight="667">
  <path
      android:pathData="M375,0V667H0V0H375ZM187.5,130C84.91,130 76,208 76,282.5C76,357 131.133,455 187.5,455C243.867,455 299,357 299,282.5C299,208 290.09,130 187.5,130Z"
      android:strokeAlpha="0.35"
      android:fillColor="#000000"
      android:fillType="evenOdd"
      android:fillAlpha="0.35"/>
  <!-- 
      The color of the mask can be changed by the android:fillColor attribute of the element below.
      The default colors are: #22CB7B (green), #E74C3C (red), #ffffff (white)
  -->
  <path
      android:pathData="--image-byte-array-"
      android:fillColor="#22CB7B"
      android:fillType="evenOdd"/>
</vector>

No. is the default for each SDK.

No. is the default for each SDK.

No. is the default for each SDK.

To create a new style, we recommend that you use the that we use, this way it will be easier to perform customizations.

To customize the masks, first create a drawable resource in your project. You can customize whiteMask, greenMask, and redMask in any way you like. We have provided generic that you can use for reference. See the setMask method definition and examples in . And see also examples of custom mask integration.

default templates
same template
document and face masks
DocumentDetector.Builder
Here
Here
Here