Skip to main content

UI Library

The Scantrust UI library is meant to provide a convenient way of setting up the UI elements of the consumer-facing scanning process.

Contents

  1. Understanding The Scanning Process
    1. UI Elements
  2. Installation
  3. Basic Layout Setup
    1. XML Details And Examples
    2. View Setup

Understanding The Scanning Process

A good understanding of the flow is necessary in order to properly set the different components up.

The regular consumer flow starts with the camera zoomed out and is in a state where it’s waiting for a code to be scanned (Read Content). If a code is read and is sufficiently centered (in a position that still makes it visible with the 4x zoom), then the zoom in is done and the controller will be waiting for a code that meets the size constraint (Fit QR). Otherwise, the user will be told that he needs to center the code (Center QR). As soon as a code meets the size constraint in the Fit QR state, the torch is turned on and as soon as the white balance is stabilised, the regular authentication process kicks in (Auth).

Three_Steps_Flow_state_graph

understanding_the_scanning_process2

UI Elements

customisable_elements

Torch icon

  • The "ON" colour is set via the torchIconColor xml custom attribute.
  • isTorchOn() give the state of the icon
  • Set a listener on the click event with setTorchOnClickListener(TorchOnClickListener listener)

Scanning window

  • Depends on the window proportion in the preview view and the camera's true zoom factor(set via setWindowProportion(float windowProportion, Size previewViewSize, float trueZoom)).
  • Managed indirectly when the scanning stage is changed (setCurrentStage(ScanStage scanStage)) or when the scanning stage is reset (resetScanningStage())

Scanning progress bar

  • The drawable is set via the android:progressDrawable xml attribute
  • The progress is managed internally when the scanning stage changes or is reset

Message bubble

  • The default background is set via the msgBackground xml custom attribute
  • The text and background can be set via the showInstructionBubble(String msg, int backgroundRes) or showInstructionBubble(String msg) methods according to the feedback given by the scanning sdk
  • The text and background can be hidden via the hideInstructionBubble().
  • Is visible by default, use the showBlurScoreProgressBarAndMsgBubble xml custom attribute or method to hide it on start-up (should normally not be touched)

Instructions Background Colour

  • The background colour of the instructions
  • Set via the scanningInstructionsBgColor xml custom attribute

Completed Instructions Text Colour

  • The colour of the instructions text when the instructions have been completed
  • Set via the scanningInstructionsFinishColor xml custom attribute

Ongoing Instructions Text Colour

  • The colour of the instructions which next need to be performed
  • Set via the scanningInstructionsProcessingColor xml custom attribute

Initial Instructions Text Colour

  • The colour of the instructions text before the user needs to perform them
  • Set via the scanningInstructionsInitColor xml custom attribute

Completed Progress Bar Icon

  • The icon that is displayed at the end of the progress bar when a scanning session has completed
  • Set via the thumbSrc xml custom attribute
  • Is shown by calling the runThumbScalingAnim() method. This will set the progress bar to 100%, set the icon visible and animates it

Scan Result Image

  • The image of the scan that is shown once a scan is complete while the request is made to the server
  • Set with the setResultImg(Bitmap bitmap) method

Loading Element

  • The indeterminate progress bar view and text
  • The text is set with the analyzeString xml custom attribute
  • The background resource is the same as the one used for the message bubble (set with the msgBackground)

Instructions Text

  • The texts are set with the instructionMsg1, instructionMsg2 and instructionMsg3 xml custom attributes
  • The texts should never change and should be:
    1. "Center the QR"
    2. "Fit the QR to the window"
    3. "Get a clear picture of the QR"

Installation

Include the UI lib as a dependency

implementation 'com.scantrust.consumer:android-ui:x.y.z'

Basic Layout Setup

The UI elements overlay the layout that holds the camera preview (c.f. prepare a layout section of the SDK).

It is integrated as a custom RelativeLayout called ConsumerScanningUi. The following custom attributes are used to modify its UI elements.

Attribute nameFormatUse
torchIconColorcolorDefines the colour of the torch icon
msgBackgroundreferenceDefines the look of the instruction bubble
thumbSrcreferenceIs the icon that is displayed when a scanning session has completed
showBlurScoreProgressBarAndMsgBubblebooleanDisplays or hides the progress bar and the message bubble
analyzeStringreferenceThe test to display when the scan is over and the image is being analysed. Recommended value: "Analysing"
instructionMsg1referenceThe first scanning instruction text. Recommended value: "Center the QR"
instructionMsg2referenceThe second scanning instruction text. Recommended value: "Fit the QR to the window"
instructionMsg3referenceThe third scanning instruction text. Recommended value: "Get a clear picture of the QR"
scanningInstructionsInitColorcolorThe colour of the instructions text before the user needs to perform them
scanningInstructionsProcessingColorcolorThe colour of the instructions text when the user needs to perform them
scanningInstructionsFinishColorcolorThe colour of the instructions text once they are completed
scanningInstructionsBgColorcolorThe background colour of the instructions

XML Details and Examples

A progress drawable can also be assigned via the android:progressDrawable attribute. E.g.

<!-- scanning_progress_bar.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="8.0dip" />
<gradient
android:startColor="#EEEEEE"
android:endColor="#EEEEEE"
android:angle="270.0" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="8.0dip" />
<gradient
android:startColor="@color/lazy_blue"
android:endColor="@color/excited_green"
android:centerColor="@color/light_cyan"
android:angle="270.0" />
</shape>
</clip>
</item>

</layer-list>

and if needed, styles can be used to aggregate the reusable attributes:

<!-- styles.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<style name="scanning_ui_style">
<item name="scanningInstructionsInitColor">@color/gray</item>
<item name="scanningInstructionsProcessingColor">@color/white_color</item>
<item name="scanningInstructionsFinishColor">@color/dark_green</item>
<item name="scanningInstructionsBgColor">@color/c031533</item>
<item name="mainColor">@color/normal_dark_groundColor</item>
<item name="msgBackground">@drawable/rounded_yellow_rectangle</item>
<item name="background">@color/black_overlay</item>
</style>
...
</resources>

with the msgBackground drawable:

<!-- rounded_yellow_rectangle.xml -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="20dp" />
<solid android:color="@color/happy_yellow" />
<stroke
android:width="20dp"
android:color="@color/happy_yellow" />
</shape>

The final layout file for the scanning screen would then look like this:

<!-- scanning_fragment.xml -->
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:scanningUI="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!--Preview layout that will hold the camera preview view-->
<RelativeLayout
android:id="@+id/preview_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/c020414"
android:gravity="center" />

<!--UI elements-->
<com.scantrust.mobile.android_ui.ConsumerScanningUi
android:id="@+id/custom_overlay"
style="@style/scanning_ui_style"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:progressDrawable="@drawable/scanning_progress_bar"
scanningUI:analyzeString="@string/analyzing"
scanningUI:instructionMsg1="@string/scanning_bottom_instructions1"
scanningUI:instructionMsg2="@string/scanning_bottom_instructions2"
scanningUI:instructionMsg3="@string/scanning_bottom_instructions3"
scanningUI:thumbSrc="@drawable/scanning_thumb" />
</android.support.constraint.ConstraintLayout>

View Setup

Once the layout files have been added and the camera parameters are set up, the ConsumerScanningUi can be inflated and initialised:

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scanning_fragment, container, false);
// setup the preview
previewLayout = view.findViewById(R.id.preview_layout);
// Get the camera preview view and add it to the layout
previewView = presenter.getController().getPreviewView();
previewLayout.addView(previewView);
previewView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
// Update the scanning window size
updateScanningWindow();
}
});
...
...
scanningUi = view.findViewById(R.id.st_scanning_ui);
// set the listener for the torch icon
scanningUi.setTorchOnClickListener(torchOnClickListener);
return view;
}
...
...
@Override
public void onCameraConfigurationDone(float trueZoomFactor) {
this.trueZoomFactor = trueZoomFactor;
// Update the scanning window size
updateScanningWindow();
}

private void updateScanningWindow() {
if (getContext() != null && trueZoomFactor != 0) {
// set the grey overlay taking into account the model's preferences and the preview dimensions
scanningUi.setCodeMinPercent(new ModelSettingsLoader(getContext()).getCodeMinPercent(),
new Size(previewView.getWidth(), previewView.getHeight()), trueZoomFactor);
}
}