[{"content":"","externalUrl":null,"permalink":"/docs/","section":"Documentation","summary":"","title":"Documentation","type":"docs"},{"content":" Welcome to the Docs # This is where you can store your structured LLM and mobile development guides. Notice how it appears in the left-hand menu!\n","externalUrl":null,"permalink":"/docs/hello-world/","section":"Documentation","summary":"Welcome to the Docs # This is where you can store your structured LLM and mobile development guides. Notice how it appears in the left-hand menu!\n","title":"Mobile Architecture","type":"docs"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/categories/android/","section":"Categories","summary":"","title":"Android","type":"categories"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/android/","section":"Tags","summary":"","title":"Android","type":"tags"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/android-development/","section":"Tags","summary":"","title":"Android-Development","type":"tags"},{"content":"Form validation is one of those features that seems simple until you start thinking about user experience. Show errors too early, and you frustrate users before they\u0026rsquo;ve even started typing. Show them too late, and users submit invalid forms repeatedly. Today, I\u0026rsquo;ll walk you through building a smart form validation system in Jetpack Compose that strikes the perfect balance.\nThe Problem with Traditional Form Validation # Most form implementations I\u0026rsquo;ve seen (and built, if I\u0026rsquo;m honest) fall into one of these traps:\nTrap #1: Aggressive Validation\n// Don\u0026#39;t do this! TextField( value = name, onValueChange = { name = it error = if (it.isEmpty()) \u0026#34;Name is required\u0026#34; else null } ) This shows errors immediately when the page loads or as soon as users clear a field. It\u0026rsquo;s technically correct but feels hostile.\nTrap #2: Passive Validation\n// Also not ideal Button(onClick = { if (name.isEmpty()) showError = true }) This only validates on submit, which means users might fill out an entire form only to discover multiple errors at the end.\nA Better Approach: Context-Aware Validation # The solution is to validate contextually based on user interaction:\n✅ Don\u0026rsquo;t show errors on initial page load ✅ Show errors if users enter text then clear it ✅ Show errors when users attempt to submit ✅ Clear errors as soon as the field becomes valid Let\u0026rsquo;s build this.\nBuilding the Reusable Component # Step 1: Enhanced Field State # First, we need to track more than just the value and error. We need to know how the user has interacted with the field:\ndata class FieldState( val value: String = \u0026#34;\u0026#34;, val error: String? = null, val isTouched: Boolean = false, val hasBeenModified: Boolean = false ) { fun shouldShowError(forceValidation: Boolean = false): Boolean { return (hasBeenModified || forceValidation) \u0026amp;\u0026amp; error != null } } Key Concepts:\nisTouched: Has the field been focused at least once? hasBeenModified: Has the user entered text and then cleared/changed it? shouldShowError(): Smart logic that decides when to display errors Step 2: The ValidatedTextField Component # Now we create a reusable composable that encapsulates this behavior:\n@Composable fun ValidatedTextField( value: String, onValueChange: (String) -\u0026gt; Unit, label: String, errorMessage: String? = null, showError: Boolean = false, onFocusChanged: ((Boolean) -\u0026gt; Unit)? = null, modifier: Modifier = Modifier, keyboardOptions: KeyboardOptions = KeyboardOptions.Default, keyboardActions: KeyboardActions = KeyboardActions.Default ) { val shouldShowError = showError \u0026amp;\u0026amp; errorMessage != null Column(modifier = modifier) { OutlinedTextField( value = value, onValueChange = onValueChange, modifier = Modifier .fillMaxWidth() .onFocusChanged { focusState -\u0026gt; onFocusChanged?.invoke(focusState.isFocused) }, placeholder = { Text(label, color = Color.Gray) }, isError = shouldShowError, colors = OutlinedTextFieldDefaults.colors( focusedBorderColor = if (shouldShowError) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, unfocusedBorderColor = if (shouldShowError) MaterialTheme.colorScheme.error else Color.Gray ), keyboardOptions = keyboardOptions, keyboardActions = keyboardActions, shape = RoundedCornerShape(8.dp) ) if (shouldShowError) { Text( text = errorMessage!!, color = MaterialTheme.colorScheme.error, fontSize = 12.sp, modifier = Modifier.padding(start = 16.dp, top = 4.dp) ) } } } Step 3: Smart State Management # Here\u0026rsquo;s where the magic happens. When users interact with the field, we update the state intelligently:\nValidatedTextField( value = firstName.value, onValueChange = { newValue -\u0026gt; val hadValue = firstName.value.isNotEmpty() firstName = FieldState( value = newValue, error = validateFirstName(newValue), isTouched = true, // Mark as modified if user had text and cleared it hasBeenModified = firstName.hasBeenModified || (hadValue \u0026amp;\u0026amp; newValue.isEmpty()) ) }, label = \u0026#34;First Name\u0026#34;, errorMessage = firstName.error, showError = firstName.shouldShowError(submitAttempted), onFocusChanged = { isFocused -\u0026gt; if (isFocused) { firstName = firstName.copy(isTouched = true) } } ) What\u0026rsquo;s happening here?\nWe track if the field previously had a value (hadValue) If it did and now it\u0026rsquo;s empty, we set hasBeenModified = true Only then do we show the error message On focus, we mark the field as touched Complete Form Example # Here\u0026rsquo;s a complete recipient details form using this pattern:\n@OptIn(ExperimentalMaterial3Api::class) @Composable fun RecipientDetailsScreen( onBackClick: () -\u0026gt; Unit = {}, onContinueClick: (Map\u0026lt;String, String\u0026gt;) -\u0026gt; Unit = {} ) { var firstName by remember { mutableStateOf(FieldState()) } var lastName by remember { mutableStateOf(FieldState()) } var submitAttempted by remember { mutableStateOf(false) } val isFormValid = firstName.error == null \u0026amp;\u0026amp; firstName.value.isNotBlank() \u0026amp;\u0026amp; lastName.error == null \u0026amp;\u0026amp; lastName.value.isNotBlank() Scaffold( topBar = { TopAppBar( title = { Text(\u0026#34;Enter Recipient Details\u0026#34;) }, navigationIcon = { IconButton(onClick = onBackClick) { Icon(Icons.Default.ArrowBack, \u0026#34;Back\u0026#34;) } } ) } ) { padding -\u0026gt; Column( modifier = Modifier .fillMaxSize() .padding(padding) .padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { ValidatedTextField( value = firstName.value, onValueChange = { newValue -\u0026gt; val hadValue = firstName.value.isNotEmpty() firstName = FieldState( value = newValue, error = if (newValue.isBlank()) \u0026#34;Please enter first name\u0026#34; else null, isTouched = true, hasBeenModified = firstName.hasBeenModified || (hadValue \u0026amp;\u0026amp; newValue.isEmpty()) ) }, label = \u0026#34;First Name\u0026#34;, errorMessage = firstName.error, showError = firstName.shouldShowError(submitAttempted) ) ValidatedTextField( value = lastName.value, onValueChange = { newValue -\u0026gt; val hadValue = lastName.value.isNotEmpty() lastName = FieldState( value = newValue, error = if (newValue.isBlank()) \u0026#34;Please enter last name\u0026#34; else null, isTouched = true, hasBeenModified = lastName.hasBeenModified || (hadValue \u0026amp;\u0026amp; newValue.isEmpty()) ) }, label = \u0026#34;Last Name\u0026#34;, errorMessage = lastName.error, showError = lastName.shouldShowError(submitAttempted) ) Spacer(modifier = Modifier.weight(1f)) Button( onClick = { submitAttempted = true firstName = firstName.copy( hasBeenModified = true, error = if (firstName.value.isBlank()) \u0026#34;Please enter first name\u0026#34; else null ) lastName = lastName.copy( hasBeenModified = true, error = if (lastName.value.isBlank()) \u0026#34;Please enter last name\u0026#34; else null ) if (isFormValid) { onContinueClick( mapOf( \u0026#34;firstName\u0026#34; to firstName.value, \u0026#34;lastName\u0026#34; to lastName.value ) ) } }, modifier = Modifier .fillMaxWidth() .height(56.dp) ) { Text(\u0026#34;Continue\u0026#34;) } } } } The User Experience # Let\u0026rsquo;s see how this plays out in real usage:\nUser Action Behavior Why? Page loads with empty fields No errors shown User hasn\u0026rsquo;t interacted yet User types \u0026ldquo;Jo\u0026rdquo; then deletes it Error appears User modified then cleared User focuses field but doesn\u0026rsquo;t type No error No modification occurred User clicks Continue with empty fields All errors appear Form submission attempted User types \u0026ldquo;John\u0026rdquo; Error clears immediately Field is now valid Performance Considerations # One concern with this approach is the frequency of recomposition. Here are some optimizations:\n1. Derivation Instead of State # For computed values like isFormValid, use derived state:\nval isFormValid by remember { derivedStateOf { firstName.error == null \u0026amp;\u0026amp; firstName.value.isNotBlank() \u0026amp;\u0026amp; lastName.error == null \u0026amp;\u0026amp; lastName.value.isNotBlank() } } 2. Stable Keys for Lists # If you have multiple fields in a list, use stable keys:\nfields.forEach { field -\u0026gt; key(field.id) { ValidatedTextField(/* ... */) } } 3. Remember Validation Functions # Cache expensive validation logic:\nval emailValidator = remember { { email: String -\u0026gt; if (!email.matches(Regex(\u0026#34;^[A-Za-z0-9+_.-]+@(.+)$\u0026#34;))) { \u0026#34;Invalid email format\u0026#34; } else null } } Testing the Component # Here\u0026rsquo;s how you can test this behavior:\n@Test fun validatedTextField_showsError_whenModifiedAndCleared() { var state by mutableStateOf(FieldState()) composeTestRule.setContent { ValidatedTextField( value = state.value, onValueChange = { newValue -\u0026gt; val hadValue = state.value.isNotEmpty() state = FieldState( value = newValue, error = if (newValue.isBlank()) \u0026#34;Required\u0026#34; else null, hasBeenModified = hadValue \u0026amp;\u0026amp; newValue.isEmpty() ) }, label = \u0026#34;Test Field\u0026#34;, errorMessage = state.error, showError = state.shouldShowError() ) } // Type and clear composeTestRule.onNodeWithText(\u0026#34;Test Field\u0026#34;).performTextInput(\u0026#34;text\u0026#34;) composeTestRule.onNodeWithText(\u0026#34;Test Field\u0026#34;).performTextClearance() // Error should appear composeTestRule.onNodeWithText(\u0026#34;Required\u0026#34;).assertIsDisplayed() } Real-World Extensions # Adding Async Validation # For backend validation (like checking username availability):\ndata class FieldState( val value: String = \u0026#34;\u0026#34;, val error: String? = null, val isValidating: Boolean = false, val isTouched: Boolean = false, val hasBeenModified: Boolean = false ) @Composable fun AsyncValidatedTextField( /* ... */, onAsyncValidate: suspend (String) -\u0026gt; String? ) { LaunchedEffect(value) { if (value.isNotEmpty()) { delay(500) // Debounce isValidating = true error = onAsyncValidate(value) isValidating = false } } // Show loading indicator when validating if (isValidating) { CircularProgressIndicator(modifier = Modifier.size(20.dp)) } } Pattern-Based Validation # Create reusable validators:\nobject Validators { fun required(message: String = \u0026#34;This field is required\u0026#34;): (String) -\u0026gt; String? { return { if (it.isBlank()) message else null } } fun email(message: String = \u0026#34;Invalid email\u0026#34;): (String) -\u0026gt; String? { return { if (!it.matches(Regex(\u0026#34;^[A-Za-z0-9+_.-]+@(.+)$\u0026#34;))) message else null } } fun minLength( length: Int, message: String = \u0026#34;Minimum $length characters\u0026#34; ): (String) -\u0026gt; String? { return { if (it.length \u0026lt; length) message else null } } } // Usage val validators = listOf( Validators.required(), Validators.email(), Validators.minLength(6) ) Conclusion # Smart form validation is about respecting your users\u0026rsquo; time and attention. By tracking interaction state and showing errors contextually, we create forms that feel helpful rather than hostile.\nThe key principles:\nTrack interaction state - Know when users have engaged with fields Validate contextually - Show errors only when meaningful Provide immediate feedback - Clear errors as soon as fields become valid Make it reusable - Build components that work consistently across your app This approach has significantly improved our form completion rates and reduced user frustration. Give it a try in your next Compose project!\nResources # Full source code on GitHub Jetpack Compose Documentation Material Design Form Guidelines Have questions or improvements? Feel free to reach out or open an issue on GitHub!\nTags: #Android #Kotlin #JetpackCompose #FormValidation #MaterialDesign #AndroidDevelopment #UX #UI\n","date":"7 October 2025","externalUrl":null,"permalink":"/posts/2025-10-07-jetpack-compose-smart-form-validation/","section":"Posts","summary":"Form validation is one of those features that seems simple until you start thinking about user experience. Show errors too early, and you frustrate users before they’ve even started typing. Show them too late, and users submit invalid forms repeatedly. Today, I’ll walk you through building a smart form validation system in Jetpack Compose that strikes the perfect balance.\nThe Problem with Traditional Form Validation # Most form implementations I’ve seen (and built, if I’m honest) fall into one of these traps:\n","title":"Building Smart Form Validation in Jetpack Compose: A UX-First Approach","type":"posts"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/compose/","section":"Tags","summary":"","title":"Compose","type":"tags"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/form-validation/","section":"Tags","summary":"","title":"Form-Validation","type":"tags"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/","section":"Home","summary":"","title":"Home","type":"home"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/categories/jetpack-compose/","section":"Categories","summary":"","title":"Jetpack Compose","type":"categories"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/jetpack-compose/","section":"Tags","summary":"","title":"Jetpack-Compose","type":"tags"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/categories/kotlin/","section":"Categories","summary":"","title":"Kotlin","type":"categories"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/kotlin/","section":"Tags","summary":"","title":"Kotlin","type":"tags"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/material-design/","section":"Tags","summary":"","title":"Material-Design","type":"tags"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"7 October 2025","externalUrl":null,"permalink":"/categories/ui/ux/","section":"Categories","summary":"","title":"UI/UX","type":"categories"},{"content":"SkiaSharp is a 2D graphics system for .NET and C# powered by the open-source Skia graphics engine that is used extensively in Google products.\nI came across a requirement to draw dynamic arabic text with specific typeface.\n{%highlight c# %} using (var eventTextShaper = new SKShaper(GetTypeface(\u0026ldquo;GESSTwoLight.ttf\u0026rdquo;))) using (SKPaint eventTextPaint = new SKPaint()) { eventTextPaint.TextAlign = SKTextAlign.Center; eventTextPaint.TextSize = 13f; eventTextPaint.Color = SKColor.Parse(\u0026quot;#dc0234\u0026quot;); eventTextPaint.Typeface = GetTypeface(\u0026ldquo;GESSTwoLight.ttf\u0026rdquo;); eventTextPaint.IsAntialias = true; var eventTitleText = \u0026ldquo;فعاليات\u0026rdquo;; var result = eventTextShaper.Shape(eventTitleText, eventTextPaint); eventTextPaint.TextEncoding = SKTextEncoding.GlyphId; var bytes = result.Codepoints.Select(cp =\u0026gt; BitConverter.GetBytes((ushort)cp)).SelectMany(b =\u0026gt; b).ToArray(); canvas.DrawText(bytes, new SKPoint(0, 50), eventTextPaint); }\n//Font by name from Embedded Resources public static SKTypeface GetTypeface(string fullFontName) { SKTypeface result; var assembly = Assembly.GetExecutingAssembly(); var stream = assembly.GetManifestResourceStream(\u0026ldquo;App.Fonts.\u0026rdquo; + fullFontName); if (stream == null) return null; using (var data = SKData.Create(stream)) { result = SKTypeface.FromData(data); } return result; } {%endhighlight%}\n","date":"1 June 2020","externalUrl":null,"permalink":"/posts/2020-05-01-skia-sharp-arabic-text/","section":"Posts","summary":"How to render arabic text in SkiaSharp Canvas using Harfbuzz.","title":"Arabic Text in SkiaSharp \u0026 Harfbuzz","type":"posts"},{"content":"","date":"1 June 2020","externalUrl":null,"permalink":"/categories/skiasharp-harfbuzz-xamarin.android-xamarin.ios-xamarin.forms-xamarin-c%23/","section":"Categories","summary":"","title":"SkiaSharp, Harfbuzz, Xamarin.Android, Xamarin.iOS, Xamarin.Forms, Xamarin, C#","type":"categories"},{"content":"SkiaSharp is a 2D graphics system for .NET and C# powered by the open-source Skia graphics engine that is used extensively in Google products.\nI came across a requirement creating a circular rotatable menu in a xamarin forms application. So, after a bit of R\u0026amp;D I found SkiaSharp can be used in Xamarin Forms for cross platform development.\nI am writing about circular menu as well will share here in future.\n","date":"1 May 2020","externalUrl":null,"permalink":"/posts/2020-05-01-skia-sharp-circular-menu/","section":"Posts","summary":"How to render arabic text in SkiaSharp Canvas using Harfbuzz.","title":"Arabic Text in SkiaSharp \u0026 Harfbuzz","type":"posts"},{"content":"","date":"1 January 2020","externalUrl":null,"permalink":"/tags/c%23/","section":"Tags","summary":"","title":"C#","type":"tags"},{"content":"","date":"1 January 2020","externalUrl":null,"permalink":"/tags/ios/","section":"Tags","summary":"","title":"IOS","type":"tags"},{"content":"","date":"1 January 2020","externalUrl":null,"permalink":"/tags/java/","section":"Tags","summary":"","title":"Java","type":"tags"},{"content":"","date":"1 January 2020","externalUrl":null,"permalink":"/tags/odata/","section":"Tags","summary":"","title":"OData","type":"tags"},{"content":"","date":"1 January 2020","externalUrl":null,"permalink":"/projects/","section":"Projects","summary":"","title":"Projects","type":"projects"},{"content":"Smart Media Platform is an interactive media solution, aimed to enhance media and information usability. The Smart Media Center puts your company\u0026rsquo;s precious multimedia collection in the palm of viewers hand seamlessly; with its light feather weight foot print it puts an end to sorry days of endless buffering, complex settings, and jumbled user interfaces.\n","date":"1 January 2020","externalUrl":null,"permalink":"/projects/smart-media/","section":"Projects","summary":"Smart Media Platform is an interactive media solution aimed at enhancing media usability.","title":"Smart Media Mobile Apps","type":"projects"},{"content":"","date":"1 January 2020","externalUrl":null,"permalink":"/tags/xamarin/","section":"Tags","summary":"","title":"Xamarin","type":"tags"},{"content":"During my current project I need to use the VideoView to play videos and add the ability to view the videos in full screen. So, I came across a good android library fullscreen-video-view.\nIn Xamarin a nice feature of Binding Library is available to bind the native platform libraries to Xamarin.\nThe Xamarin Binding Project along with the sample Xamarin Android App is available here. XamarinAndroidFullScreenVideoView\n","date":"30 July 2019","externalUrl":null,"permalink":"/posts/2019-07-30-xamarin-android-fullscreen-videoview/","section":"Posts","summary":"Xamarin Android Binding for FullscreenVideoView.","title":"Xamarin Android FullScreen Video View","type":"posts"},{"content":"","date":"30 July 2019","externalUrl":null,"permalink":"/categories/xamarin.android-xamarin.android-binding-xamarin-c%23/","section":"Categories","summary":"","title":"Xamarin.Android, Xamarin.Android Binding, Xamarin, C#","type":"categories"},{"content":"In order to share content from xamarin android native application, 2 options are available.\n","date":"7 April 2019","externalUrl":null,"permalink":"/posts/2019-04-07-xamarin.android-sharing/","section":"Posts","summary":"Different ways of sharing UI in Xamarin Android.","title":"Xamarin Android Native Sharing","type":"posts"},{"content":"","date":"7 April 2019","externalUrl":null,"permalink":"/categories/xamarin.android-xamarin-c%23/","section":"Categories","summary":"","title":"Xamarin.Android, Xamarin, C#","type":"categories"},{"content":"In one of the projects, client require to built a design where a secondary drawer will opened over already opened primary drawer.\nAs per Android Material Design guidelines its not recommended and its not implemented in android.support.v4.widget.DrawerLayout. If we try to implement it in code like following, it throws exception, only one drawer can be shown.\n{%highlight xml %}\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e \u0026lt;android.support.v4.widget.DrawerLayout xmlns:android=\u0026ldquo;http://schemas.android.com/apk/res/android\" xmlns:app=\u0026ldquo;http://schemas.android.com/apk/res-auto\" android:id=\u0026rdquo;@+id/drawer_layout\u0026rdquo; android:layout_width=\u0026ldquo;match_parent\u0026rdquo; android:layout_height=\u0026ldquo;match_parent\u0026rdquo; android:fitsSystemWindows=\u0026ldquo;true\u0026rdquo;\u0026gt; \u0026lt;android.support.design.widget.NavigationView android:id=\u0026quot;@+id/first_nav_view\u0026quot; android:layout_width=\u0026ldquo;wrap_content\u0026rdquo; android:layout_height=\u0026ldquo;match_parent\u0026rdquo; android:layout_gravity=\u0026ldquo;start\u0026rdquo; android:fitsSystemWindows=\u0026ldquo;true\u0026rdquo; /\u0026gt; \u0026lt;android.support.design.widget.NavigationView android:id=\u0026quot;@+id/second_nav_view\u0026quot; android:layout_width=\u0026ldquo;wrap_content\u0026rdquo; android:layout_height=\u0026ldquo;match_parent\u0026rdquo; android:layout_gravity=\u0026ldquo;start\u0026rdquo; android:fitsSystemWindows=\u0026ldquo;true\u0026rdquo; /\u0026gt; \u0026lt;/android.support.v4.widget.DrawerLayout\u0026gt; {%endhighlight%}\nTo show both drawers from same side we need to extend the android.support.v4.widget.DrawerLayout to handle the navigation of secondary drawer over primary.\n","date":"5 January 2019","externalUrl":null,"permalink":"/posts/2019-01-05-android-double-drawer-layout/","section":"Posts","summary":"How to show secondary drawer in android material drawers over primary.","title":"Two Drawer Layouts from Same Side in Xamarin.Android","type":"posts"},{"content":"","date":"5 January 2019","externalUrl":null,"permalink":"/categories/xamarin.android/","section":"Categories","summary":"","title":"Xamarin.Android","type":"categories"},{"content":"","date":"1 January 2019","externalUrl":null,"permalink":"/tags/automation/","section":"Tags","summary":"","title":"Automation","type":"tags"},{"content":"","date":"1 January 2019","externalUrl":null,"permalink":"/tags/c++/","section":"Tags","summary":"","title":"C++","type":"tags"},{"content":"Utilize the cutting edge technology to provide publications for press clippings in Middle East and North Africa (MENA).\n","date":"1 January 2019","externalUrl":null,"permalink":"/projects/clipping-station/","section":"Projects","summary":"Utilize cutting-edge technology to provide publications for press clippings in the MENA region.","title":"Clipping Station","type":"projects"},{"content":"","date":"1 January 2019","externalUrl":null,"permalink":"/tags/mysql/","section":"Tags","summary":"","title":"MySQL","type":"tags"},{"content":"","date":"1 January 2019","externalUrl":null,"permalink":"/tags/ocr/","section":"Tags","summary":"","title":"OCR","type":"tags"},{"content":"","date":"1 January 2019","externalUrl":null,"permalink":"/tags/qt/","section":"Tags","summary":"","title":"Qt","type":"tags"},{"content":"","date":"1 January 2019","externalUrl":null,"permalink":"/tags/ubuntu/","section":"Tags","summary":"","title":"Ubuntu","type":"tags"},{"content":"Microsoft release the Xamarin forms 4.0.0 early preview at its Connect conference, along with the release of Xamarin forms 3.4.0(Stable).\nXamarin Forms new features:\nShell Visual CollectionView \u0026lt;3 CarouselView One more requested on github, which I was also thinking about \u0026lsquo;Colored Refresh Indicator\u0026rsquo; ","date":"3 December 2018","externalUrl":null,"permalink":"/posts/2018-12-03-xamarin.forms-4.0.0-pre1/","section":"Posts","summary":"Big Changes in Xamarin.Forms 4.0 Prompt Early Preview.","title":"Xamarin.Forms 4.0.0-pre1","type":"posts"},{"content":"","date":"3 December 2018","externalUrl":null,"permalink":"/categories/xamarinforms/","section":"Categories","summary":"","title":"XamarinForms","type":"categories"},{"content":"Abu Dhabi Chamber of Commerce Mobile Apps that will facilitate the users to create/update COO and get updated with Commercial directory.\n","date":"1 January 2018","externalUrl":null,"permalink":"/projects/abu-dhabi-chamber/","section":"Projects","summary":"Mobile Apps that facilitate users to create/update COO and view the Commercial directory.","title":"Abu Dhabi Chamber of Commerce","type":"projects"},{"content":"","date":"1 January 2018","externalUrl":null,"permalink":"/tags/asp.net/","section":"Tags","summary":"","title":"ASP.NET","type":"tags"},{"content":"","date":"1 February 2017","externalUrl":null,"permalink":"/tags/afnetworking/","section":"Tags","summary":"","title":"AFNetworking","type":"tags"},{"content":"","date":"1 February 2017","externalUrl":null,"permalink":"/tags/retrofit/","section":"Tags","summary":"","title":"Retrofit","type":"tags"},{"content":"Sharjah 24 is an online news portal based in the emirate of Sharjah. The site aims to become a reliable news reference covering all events in the emirate of Sharjah.\n","date":"1 February 2017","externalUrl":null,"permalink":"/projects/sharjah-24/","section":"Projects","summary":"An online news portal based in Sharjah, serving as a reliable news reference for the UAE.","title":"Sharjah24","type":"projects"},{"content":"","date":"1 February 2017","externalUrl":null,"permalink":"/tags/swift/","section":"Tags","summary":"","title":"Swift","type":"tags"},{"content":"","date":"1 January 2017","externalUrl":null,"permalink":"/tags/.net-core/","section":"Tags","summary":"","title":".NET Core","type":"tags"},{"content":"","date":"1 January 2017","externalUrl":null,"permalink":"/tags/angular/","section":"Tags","summary":"","title":"Angular","type":"tags"},{"content":"Sharjah Events is the official website for events held in Sharjah, UAE, throughout the year.\n","date":"1 January 2017","externalUrl":null,"permalink":"/projects/sharjah-events/","section":"Projects","summary":"The official website and mobile apps for events held in Sharjah, UAE, throughout the year.","title":"Sharjah Events","type":"projects"},{"content":"","date":"1 January 2017","externalUrl":null,"permalink":"/tags/xamarin.forms/","section":"Tags","summary":"","title":"Xamarin.Forms","type":"tags"},{"content":"The VA Consumer app, powered by CORE, is a mobile experience for retail shoppers. It is one app in an ecosystem of apps that constitute the touch points of a retail customer.\n","date":"1 January 2016","externalUrl":null,"permalink":"/projects/nyc-consumer-app/","section":"Projects","summary":"A mobile experience for retail shoppers, powered by CORE, enabling a connected shopping experience.","title":"NYC Consumer App","type":"projects"},{"content":"CORE is a platform which produces a unified user experience across all devices with accelerated provisioning for new, innovative business applications.\n","date":"1 January 2015","externalUrl":null,"permalink":"/projects/core-framework/","section":"Projects","summary":"A platform producing a unified user experience across devices with accelerated provisioning.","title":"Core Framework","type":"projects"},{"content":"","date":"1 January 2014","externalUrl":null,"permalink":"/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"NCR\u0026rsquo;s Radiant Site Manager (RSM) is an application that includes more than 60 real-time reports and reconciliation applets that show common fraudulent activities. This software increases store system availability and streamlines the support process.\n","date":"1 January 2014","externalUrl":null,"permalink":"/projects/radiant-site-manager/","section":"Projects","summary":"NCR’s site manager application with 60+ real-time reports and reconciliation applets.","title":"Radiant Site Manager (RSM)","type":"projects"},{"content":"","date":"1 January 2014","externalUrl":null,"permalink":"/tags/sql/","section":"Tags","summary":"","title":"SQL","type":"tags"}]