Jetpack Compose
Starting with Android NeuroID SDK version 3.4.0, NeuroID offers comprehensive support for Jetpack Compose. The enhanced feature set includes several methods to effectively track user interactions and behavior within your Compose-based UI, including things like TextField input, paste events, and screen transitions.
The new methods:
- must be placed within the Composable UI.
- must (each) specify a page and/or an element name.
- must be placed within your Composable functions to capture the relevant interactions and user inputs.
This approach ensures that the SDK will have detailed and accurate tracking data for analyzing user behavior and safeguarding your application's user experience.
We recommended placing NeuroID functions immediately before the UI Compose Elements (see code examples below).
Is your Android SDK installation complete?
Ensure you've successfully completed the Android SDK installation instructions before continuing since it is easier to install and configure the SDK prior to integrating the Compose specific components.
Available Jetpack Compose Methods
- trackPageElements
- trackPage
- trackElement
- trackButtonTap
- trackElementOnChange
New Methods for Tracking in Jetpack Compose
trackPageElements
trackPageElements
This method tracks the page and multiple TextFields or UI elements simultaneously, capturing the text and associating it with the corresponding element and page. This method simplifies tracking across multiple elements on a single screen.
Parameters | Type |
---|---|
pageName | String |
elements | Array<Pair<String, String>> |
Returns |
---|
Void |
NeuroID.compose?.trackPageElements(
pageName: String,
elements: Array<Pair<elementName: String, elementState: String>>
)
Example of the trackPageElements
method placed inside a Composable function LoginView() [lines 9-16]:
@Composable
fun LoginView() {
val colorBackground = activity?.resources?.getColor(R.color.nid_green_light)?:0
val colorText = activity?.resources?.getColor(R.color.white)?:0
var email by remember { mutableStateOf(TextFieldValue(""))}
var password by remember { mutableStateOf(TextFieldValue("")) }
// *** here is our trackPageElements() call ***
NeuroID.compose?.trackPageElements(
pageName = "loginPage",
elements = arrayOf(
Pair(first = "email", second = email.text),
Pair(first = "pasword", second = password.text),
)
)
Row {
Column(modifier = Modifier
.padding(40.dp)
.fillMaxWidth()) {
OutlinedTextField(
value = email,
onValueChange = {email = it},
label = {Text("email", color = Color(colorBackground))},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(colorBackground),
cursorColor = Color(colorBackground)
)
)
OutlinedTextField(
value = password,
onValueChange = {password = it},
visualTransformation = PasswordVisualTransformation(),
label = {Text("password", color = Color(colorBackground))},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(colorBackground),
cursorColor = Color(colorBackground)
)
)
}
}
}
}
trackPage
trackPage
This method tracks when a user navigates to a specific page or screen within your application.
Parameters | Type |
---|---|
pageName | String |
Returns |
---|
Void |
NeuroID.compose?.trackPage(
pageName: String
)
Example of the trackPage
method placed inside a Composable function LoginView() [line 9-10]:
@Composable
fun LoginView() {
val colorBackground = activity?.resources?.getColor(R.color.nid_green_light)?:0
val colorText = activity?.resources?.getColor(R.color.white)?:0
var email by remember { mutableStateOf(TextFieldValue(""))}
var password by remember { mutableStateOf(TextFieldValue("")) }
// *** here is our trackPage() call ***
NeuroID.compose?.trackPage(pageName = "loginPage")
Row {
Column(modifier = Modifier
.padding(40.dp)
.fillMaxWidth()) {
OutlinedTextField(
value = email,
onValueChange = {email = it},
label = {Text("email", color = Color(colorBackground))},
.
.
.
}
}
}
trackElement
trackElement
This method tracks input events within a specific TextField, capturing the text entered or pasted by the user. This method also associates the input with a particular element and page.
Parameters | Type |
---|---|
elementState | String |
elementName | String |
pageName | String |
Returns |
---|
Void |
NeuroID.compose?.trackElement(
elementState:String,
elementName:String,
pageName: String
)
Example of the trackElement
method placed inside a Composable function LoginView() [lines 9-11]:
@Composable
fun LoginView() {
val colorBackground = activity?.resources?.getColor(R.color.nid_green_light)?:0
val colorText = activity?.resources?.getColor(R.color.white)?:0
var email by remember { mutableStateOf(TextFieldValue(""))}
var password by remember { mutableStateOf(TextFieldValue("")) }
// *** here is our trackElement() calls ***
NeuroID.compose?.trackElement(email.text, "email", pageName = "loginPage")
NeuroID.compose?.trackElement(password.text, "password", pageName = "loginPage")
Row {
Column(modifier = Modifier
.padding(40.dp)
.fillMaxWidth()) {
OutlinedTextField(
value = email,
onValueChange = {email = it},
label = {Text("email", color = Color(colorBackground))},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(colorBackground),
cursorColor = Color(colorBackground)
)
)
OutlinedTextField(
value = password,
onValueChange = {password = it},
visualTransformation = PasswordVisualTransformation(),
label = {Text("password", color = Color(colorBackground))},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(colorBackground),
cursorColor = Color(colorBackground)
)
)
}
}
}
}
trackButtonTap
trackButtonTap
This method tracks when a specific button is tapped, capturing the button’s identifier and the associated screen.
Note: This must be placed inside the Button's onClick() callback.
Parameters | Type |
---|---|
elementName | String |
pageName | String |
Returns |
---|
Void |
NeuroID.compose?.trackButtonTap(
elementName:String,
pageName: String
)
Example of the trackButtonTap
method placed inside a Composable function LoginView() [line 15-16].
@Composable
fun LoginView() {
val colorBackground = activity?.resources?.getColor(R.color.nid_green_light)?:0
val colorText = activity?.resources?.getColor(R.color.white)?:0
var email by remember { mutableStateOf(TextFieldValue(""))}
var password by remember { mutableStateOf(TextFieldValue("")) }
Row (modifier = Modifier
.padding(40.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = {
// *** here is our trackButtonTap() call ***
NeuroID.compose?.trackButtonTap("login", "loginPage")
(activity as Login).login(email.text)
},
colors = ButtonDefaults.buttonColors(
backgroundColor = Color(colorBackground),
contentColor = Color(colorText))
) {
Text(text = "login")
}
}
trackElementOnChange
trackElementOnChange
This method provides an alternative way to track input events within a specific TextField if the trackElement
method syntax is not available. This method also associates the input with a particular element and page.
Note:: This method must be placed inside the TextField's onValueChange() callback.
Parameters | Type |
---|---|
oldState | String |
newState | String |
elementName | String |
pageName | String |
Returns |
---|
Void |
NeuroID.compose?.trackElementOnChange(
oldState: String,
newState: String,
elementName: String,
pageName: String,
)
Example of the trackElementOnChange
method placed inside a Composable function LoginView() [line 16-22].
@Composable
fun LoginView() {
val colorBackground = activity?.resources?.getColor(R.color.nid_green_light)?:0
val colorText = activity?.resources?.getColor(R.color.white)?:0
var email by remember { mutableStateOf(TextFieldValue(""))}
var password by remember { mutableStateOf(TextFieldValue("")) }
Row (modifier = Modifier
.padding(40.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween) {
OutlinedTextField(
value = password,
onValueChange = {
// *** here is our trackElementOnChange() call ***
NeuroID.compose?.trackElementOnChange(
password,
it,
"password",
"loginPage"
)
password = it
},
visualTransformation = PasswordVisualTransformation(),
label = {Text("password", color = Color(colorBackground))},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(colorBackground),
cursorColor = Color(colorBackground)
)
)
}
Troubleshooting
A java.lang.NoSuchMethodError exception occurs during compose operations, causing a crash in your application:
The most likely cause for this issue is that the compose library version(s) specified in your dependencies are getting overridden by a compose version that is included in the NeuroID SDK. The Android NeuroID SDK uses Compose 1.7.3. We've seen situations where customers were using compose 1.4.3, and relied on some methods that were changed in 1.7.x which caused their application to crash. To see if this may be causing your issue:
- Check your application compose version using the command "./gradlew app:dependencies" to see if this applies to you
- If it does apply, try excluding and/or forcing a compose library version in your "app/build.gradle" file. It will look something like the following example:
configurations.all {
resolutionStrategy {
force "androidx.compose.ui:ui:<compose version to force to>"
force "androidx.compose.material:material:<compose version to force to>"
force "androidx.compose.foundation:foundation:<compose version to force to>"
}
}
dependencies {
.
.
implementation ("com.github.Neuro-ID.neuroid-android-sdk:android-sdk:<neuroid_sdk>") {
exclude group: "androidx.compose.ui", module: "ui"
exclude group: "androidx.compose.ui", module: "ui-util-android"
exclude group: "androidx.compose.material", module: "material"
exclude group: "androidx.compose.foundation", module: "foundation"
}
.
.
}
Updated 4 months ago