Customization
Learn how to customize our SDK and make it look like your app.
Custom layout creation
To create a new layout we recommend that you use the default templates from the SDKs and make the desired changes.
Step-by-step
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
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:
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
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:
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
.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.
No. Here is the default for each SDK.
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.
No. Here is the default for each SDK.
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.
No. Here is the default for each SDK.
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
To create a new style, we recommend that you use the same template that we use, this way it will be easier to perform customizations.
Customization of masks
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 document and face masks that you can use for reference. See the setMask
method definition and examples in DocumentDetector.Builder. And see also examples of custom mask integration.
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 && 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>
Last updated