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
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).
UI 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)
orshowInstructionBubble(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
andinstructionMsg3
xml custom attributes - The texts should never change and should be:
- "Center the QR"
- "Fit the QR to the window"
- "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 name | Format | Use |
---|---|---|
torchIconColor | color | Defines the colour of the torch icon |
msgBackground | reference | Defines the look of the instruction bubble |
thumbSrc | reference | Is the icon that is displayed when a scanning session has completed |
showBlurScoreProgressBarAndMsgBubble | boolean | Displays or hides the progress bar and the message bubble |
analyzeString | reference | The test to display when the scan is over and the image is being analysed. Recommended value: "Analysing" |
instructionMsg1 | reference | The first scanning instruction text. Recommended value: "Center the QR" |
instructionMsg2 | reference | The second scanning instruction text. Recommended value: "Fit the QR to the window" |
instructionMsg3 | reference | The third scanning instruction text. Recommended value: "Get a clear picture of the QR" |
scanningInstructionsInitColor | color | The colour of the instructions text before the user needs to perform them |
scanningInstructionsProcessingColor | color | The colour of the instructions text when the user needs to perform them |
scanningInstructionsFinishColor | color | The colour of the instructions text once they are completed |
scanningInstructionsBgColor | color | The 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);
}
}