SlideShare a Scribd company logo
Building complex
screens on
Android
Maciej Witowski
April 10th 2019, 1pm
Usability
#ZES19
Let’s get started!
Check-in to the session
on the App!
Turn on the Zoom! Record the Zoom!
#ZES19
A long time ago...
A long time ago...
A long time ago...
● One of the top mobile CRMs
in App Store and Play Store
● 8000 paying users
● Offline mode, Voice, Calendar, Maps etc.
● Average screen time at 71 minutes per day
With a lot of features comes a lot of responsibility
With a lot of features comes a lot of responsibility
many lines of code
> 400k LOC
This talk
Old vs New way of building screens
Main types of objects in Sell
Main types of objects in Sell
Contact
Company
Person
Lead
Deal
Main types of objects in Sell
Contact
Company
Person
Lead
Deal
Main types of objects in Sell
Contact
Company
Person
Lead
Deal
You can create new
objects and edit
existing ones
Our task
Build the edit screens for these objects
The Old Way
Types Edit Screens
Contact
Company
Person
Lead
Deal
Types Edit Screens
Contact
Company
Person
Lead
Deal
ContactEditFragment
CompanyEditFragment
PersonEditFragment
DealEditFragment
LeadEditFragment
Fragment per object type
● Huge classes containing both view and logic
● Deep inheritance hierarchy
● Duplicated functionality
BaseFragment
Fragment
ContactEditFragment
CompanyEditFragment
Callbacks everywhere
● No clear direction
● Confusing lifecycle
● Problematic events handling
● Errors propagation
@OnClick(R.id.show_company)
private void onClick() {
Loader<Company> loader = new Loader<Company>(){
@Override
public void onLoadFinished(Company company) {
setCompanyData(company);
}
};
initLoader(loader);
}
Mutable state
● Extreme complexity growth
● Hard to debug
● Concurrency problem
private ContactData initialContactData;
private ContactData currentContactData;
private ContactData temporaryContactData;
private boolean isErrorShown;
private boolean canSaveNow;
Coupling with Android SDK
● No boundary between business logic and platform code
● Handling quirky APIs
● No way to unit test
● Espresso not ready
Modeling with primitives
● No built-in support for value objects in Java
● Working with Android SDK
Modeling with primitives
● No built-in support for value objects in Java
● Working with Android SDK
● “Performance impact”
Old times - sum up
● Inheritance
● Callbacks
● Mutable state
● Coupling with the Android SDK
● Lack of tests
● Modeling the logic using primitives
Time went by...
Time went by...
● Building many new screens
● Exploring new patterns, mostly Model-View-Presenter
● New tools, Kotlin, RxJava, Espresso
Time went by...
● Building many new screens
● Exploring new patterns, mostly Model-View-Presenter
● New tools: Kotlin, RxJava, Espresso
When it comes to the edit screens
● Small product changes
● Didn’t justify the investment
● Sticking the new code and hoping it will work
2017: Required Fields
What is a better way to build screens?
Unidirectional Data Flow
StoreView
State
Actions
Unidirectional Data Flow
StoreView
State
https://github.com/zendesk/Suas-Android
Actions
Unidirectional Data Flow
View Reducer
Fields Builder
Configuration
Provider
Store
Unidirectional Data Flow
Unidirectional Data Flow
name: null,
phone: null
Unidirectional Data Flow
name: null,
phone: null
name: null,
phone: null
Unidirectional Data Flow
name: null,
phone: null
field(name: null),
field(phone: null)
name: null,
phone: null
Unidirectional Data Flow
name: null,
phone: null
field(name: null),
field(phone: null)
name: null,
phone: null
field(name: null),
field(phone: null)
Unidirectional Data Flow
field(name: null),
field(phone: null)
name: null,
phone: null
field(name: null),
field(phone: null)
name: null,
phone: null
Unidirectional Data Flow
field(name: null),
field(phone: null)
name: null,
phone: null
field(name: null),
field(phone: null)
name: null,
phone: null
name: “Joe”
Unidirectional Data Flow
field(name: null),
field(phone: null)
name: Joe,
phone: null
field(name: null),
field(phone: null)
name: null,
phone: null
Unidirectional Data Flow
field(name: null),
field(phone: null)
name: Joe,
phone: null
name: null,
phone: null
field(name: Joe),
field(phone: null)
Unidirectional Data Flow
field(name: null),
field(phone: null)
name: Joe,
phone: null
name: null,
phone: null
field(name: Joe),
field(phone: null)
field(name: Joe),
field(phone: null)
Unidirectional Data Flow
field(name: “Joe”),
field(phone: null)
name: Joe,
phone: null
name: null,
phone: null
field(name: Joe),
field(phone: null)
Unidirectional Data Flow
field(name: “Joe”),
field(phone: null)
name: Joe,
phone: null
name: null,
phone: 555
field(name: Joe),
field(phone: null)
Unidirectional Data Flow
field(name: “Joe”),
field(phone: null)
name: Joe,
phone: 555
name: null,
phone: 555
field(name: Joe),
field(phone: null)
Unidirectional Data Flow
field(name: “Joe”),
field(phone: null)
name: Joe,
phone: 555
name: null,
phone: 555
field(name: Joe),
field(phone: 555)
Unidirectional Data Flow
field(name: “Joe”),
field(phone: null)
name: Joe,
phone: 555
name: null,
phone: 555
field(name: Joe),
field(phone: 555)
field(name: Joe),
field(phone: 555)
Unidirectional Data Flow
field(name: “Joe”),
field(phone: “555”)
name: Joe,
phone: 555
name: null,
phone: 555
field(name: Joe),
field(phone: 555)
Is that it?
Is that it?
● Database changes
● Handling conflicts
● Different field types
● Sections, ordering
● Filtering
● Navigation
● Prefilled values
● Validations
● Persisting
● Confirmations, discarding changes
● ...
Configuration
Provider Reducer
Fields Builder
View
Store - key concepts
● Directed acyclic graph
● Single Store and Reducer implementations
● Unit tested the most
● Composition of simple dependencies unique per business type
● Dagger as a glue
Implementation
Implementation
class Store<FieldIdentifier>(
private val reducer: Reducer<FieldIdentifier>,
private val layoutProcessor: LayoutProcessor<FieldIdentifier>,
private val fieldsBuilder: FieldsBuilder<FieldIdentifier>,
//…
) {
fun start(initialState: State<FieldIdentifier>) {
//…
}
fun stop() {
//...
}
}
Implementation
class Store<FieldIdentifier>(
private val reducer: Reducer<FieldIdentifier>,
private val layoutProcessor: LayoutProcessor<FieldIdentifier>,
private val fieldsBuilder: FieldsBuilder<FieldIdentifier>,
//…
) {
fun start(initialState: State<FieldIdentifier>) {
//…
}
fun stop() {
//...
}
}
Implementation
class Store<FieldIdentifier>(
private val reducer: Reducer<FieldIdentifier>,
private val layoutProcessor: LayoutProcessor<FieldIdentifier>,
private val fieldsBuilder: FieldsBuilder<FieldIdentifier>,
//…
) {
fun start(initialState: State<FieldIdentifier>) {
//…
}
fun stop() {
//...
}
}
Implementation
class Reducer<FieldIdentifier> {
fun reduce(
fields: Observable<Set<FieldIdentifier>>,
userUpdates: Observable<Set<FieldIdentifier>>,
//...
): Observable<State<FieldIdentifier>>
}
Implementation
class Reducer<FieldIdentifier> {
fun reduce(
fields: Observable<Set<FieldIdentifier>>,
userUpdates: Observable<Set<FieldIdentifier>>,
//...
): Observable<State<FieldIdentifier>> {
return Observable
.merge(fields, userUpdated /* ... */)
.scan(initialState) { state, event ->
// Build new state
}
}
}
Implementation
sealed class ContactFieldIdentifier {
object Name : ContactFieldIdentifier()
object Phone : ContactFieldIdentifier()
sealed class ContactSectionIdentifier : ContactFieldIdentifier() {
object DefaultSection : ContactSectionIdentifier()
object ContactInformationSection : ContactSectionIdentifier()
}
}
Implementation
class ContactConfigurationProvider : ConfigurationProvider<ContactFieldIdentifier> {
fun getFields(): Observable<Set<ContactFieldIdentifier>>
//...
}
}
class ContactFieldValuesProvider : FieldValuesProvider<ContactFieldIdentifier> {
fun getFieldValues(fields: Set<ContactFieldIdentifier>):
Observable<Map<ContactFieldIdentifier, Value?>> {
//...
}
}
sealed class Value {
data class LongValue(val value: Long) : Value()
data class StringValue(val value: String) : Value()
//...
}
The graph
The graph - challenges
● Responsibilities
● Invalidations
● Side effects
● Unexpected requirements
The graph - challenges
● Clear flow
● Threading
● Debugging
● Extensibility
Cycles
View
Reducer
Configuration
Provider
Store
Fields Builder
View
Reducer
Configuration
Provider
Store
Display Values
Provider
Fields Builder
View
name: Joe,
company: 1
Store
View
name: Joe,
company: 1
name: Joe,
company: 1
Store
View
name: Joe,
company: 1
name: Joe,
company: 1
Store
name: Joe,
company: VW
View
name: Joe,
company: 1
name: Joe,
company: 1
Store
name: Joe,
company: VW
field(name: Joe),
field(company: {1, VW})
View
name: Joe,
company: 1
name: Joe,
company: 1
Store
name: Joe,
company: VW
field(name: Joe),
field(company: {1, VW})
View
name: Joe,
company: 1
name: Joe,
company: 1
Store
name: Joe,
company: VW
field(name: Joe),
field(company: 1)
Fallback:
company: null
View
name: Joe,
company: null
name: Joe,
company: 1
Store
name: Joe,
company: VW
field(name: Joe),
field(company: 1)
Fallback:
company: null
View
name: Joe,
company: null
name: Joe,
company: 1
Store
name: Joe,
company: null
field(name: Joe),
field(company: null)
Fallback:
company: null
View
name: Joe,
company: null
name: Joe,
company: 1
Store
name: Joe,
company: null
field(name: Joe),
field(company: null)
Fallback:
company: null
Cycles
● Limit or remove
● Rethink early
● Watch out for Rx Subjects
View effects
View effects
● Scroll to a field, show Snackbar, close the screen
StoreView
State
Actions
View effects
● Scroll to a field, show Snackbar, close the screen
● Option 1: Pass them in State
StoreView
State
Actions
field(name: Joe),
effect(scroll to top)
View effects
● Scroll to a field, show Snackbar, close the screen
● Option 1: Pass them in State
StoreView
State
Actions
field(name: Joe),
effect(null)
View effects
● Scroll to a field, show Snackbar, close the screen
● Option 1: Pass them in State
● Option 2: Separate them
StoreView
State
Actions
effect(scroll to top)
A few more things
● Data modeling
● Separation from Android
● Mapping data to views
● Development process
● Future improvements
A few more things
● Data modeling
● Separation from Android
● Mapping data to views
● Development process
● Future improvements
Data modeling
● Kotlin is a major improvement over Java
Data classes, sealed classes, extension functions, lambdas
Data modeling
● Kotlin is a major improvement over Java
Data classes, sealed classes, extension functions, lambdas
● Android Runtime improvements
“Creating garbage is OK. Use the types and objects you need.”
Nicolas Geoffray, Android Runtime Team
A few more things
● Data modeling
● Separation from Android
● Mapping data to views
● Development process
● Future improvements
Separation from Android
● Build wrapper classes with interfaces and clear API
● Abstraction increase
● Designing an API will be on you!
fun requestPermissions(
usage: RuntimePermissionsUsage
): Observable<RuntimePermissionsResult>
A few more things
● Data modeling
● Separation from Android
● Mapping data to views
● Development process
● Future improvements
Mapping data to views
Mapping data to views
Epoxy
● Abstraction over RecyclerView
● Kotlin support, many add ons
EpoxyTouchHelper
.initSwiping(recyclerView)
.leftAndRight()
.withTarget(MySwippableModel::class.java)
.andCallbacks(swipeCallback)
A few more things
● Data modeling
● Separation from Android
● Mapping data to views
● Development process
● Future improvements
Development process
● Significant entry level
● Proficiency in reactive programming
Development process
● Significant entry level
● Proficiency in reactive programming
● Duplication and copy-pasting
“Prefer duplication over the wrong abstraction”
Sandi Metz
A few more things
● Data modeling
● Separation from Android
● Mapping data to views
● Development process
● Future improvements
Future improvements
● Splitting the Store (~200 LOC)
● Reevaluating existing cyclic dependencies
● More type-safe modelling
● Developer experience
○ Initial setup
○ Unified naming
○ Tracking or rewinding state
Conclusion
Conclusion
Old New
Inheritance Composition
Callbacks RxJava-based blocks
Mutable state Unidirectional flow
Modeling with primitives Higher level abstractions with Kotlin
No separation from Android SDK Android SDK kept in isolated blocks
Lack of tests
Unit tests for the core logic, Espresso
for integrations
Questions?
Thanks!
Don’t Forget!
Fill out the Session
Survey in the App
End Zoom Recording
Leave the room better
than you found it!
#ZES19
#ZES19

More Related Content

Similar to Building complex UI on Android

Agile Database Development with JSON
Agile Database Development with JSONAgile Database Development with JSON
Agile Database Development with JSON
Chris Saxon
 
Evolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB StitchEvolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB Stitch
MongoDB
 
Yesplan: 10 Years later
Yesplan: 10 Years laterYesplan: 10 Years later
Yesplan: 10 Years later
Pharo
 
Fast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDBFast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDB
MongoDB
 
PoEAA by Example
PoEAA by ExamplePoEAA by Example
PoEAA by Example
Paulo Gandra de Sousa
 
Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)
Paulo Gandra de Sousa
 
Resume_Sharvani
Resume_SharvaniResume_Sharvani
Resume_Sharvani
Sharvani Pamarthi
 
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
Ted Chien
 
Android_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_EngineeringAndroid_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_Engineering
ShivanshSeth6
 
React native: building shared components for Android and iOS
React native: building shared components for Android and iOSReact native: building shared components for Android and iOS
React native: building shared components for Android and iOS
Calum Gathergood
 
Notes (2012-06-08)
Notes (2012-06-08)Notes (2012-06-08)
Notes (2012-06-08)
Chris Pitt
 
MongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB StitchMongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB
 
Huge web apps web expo 2013
Huge web apps web expo 2013Huge web apps web expo 2013
Huge web apps web expo 2013
Daniel Steigerwald
 
Breaking the oracle tie
Breaking the oracle tieBreaking the oracle tie
Breaking the oracle tie
agiamas
 
PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...
predictionio
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB
 
Pre-Aggregated Analytics And Social Feeds Using MongoDB
Pre-Aggregated Analytics And Social Feeds Using MongoDBPre-Aggregated Analytics And Social Feeds Using MongoDB
Pre-Aggregated Analytics And Social Feeds Using MongoDB
Rackspace
 
From Monkey Coders To Smart Gorillas - Web Summit 2014
From Monkey Coders To Smart Gorillas - Web Summit 2014From Monkey Coders To Smart Gorillas - Web Summit 2014
From Monkey Coders To Smart Gorillas - Web Summit 2014
José Ignacio Fernández
 
Rockin' the Web into the Next Dimension: JQueryTO 2014 Final Keynote
Rockin' the Web into the Next Dimension: JQueryTO 2014 Final KeynoteRockin' the Web into the Next Dimension: JQueryTO 2014 Final Keynote
Rockin' the Web into the Next Dimension: JQueryTO 2014 Final Keynote
Verold
 
Google Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talkGoogle Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talk
Imam Raza
 

Similar to Building complex UI on Android (20)

Agile Database Development with JSON
Agile Database Development with JSONAgile Database Development with JSON
Agile Database Development with JSON
 
Evolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB StitchEvolving your Data Access with MongoDB Stitch
Evolving your Data Access with MongoDB Stitch
 
Yesplan: 10 Years later
Yesplan: 10 Years laterYesplan: 10 Years later
Yesplan: 10 Years later
 
Fast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDBFast REST APIs Development with MongoDB
Fast REST APIs Development with MongoDB
 
PoEAA by Example
PoEAA by ExamplePoEAA by Example
PoEAA by Example
 
Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)
 
Resume_Sharvani
Resume_SharvaniResume_Sharvani
Resume_Sharvani
 
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
 
Android_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_EngineeringAndroid_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_Engineering
 
React native: building shared components for Android and iOS
React native: building shared components for Android and iOSReact native: building shared components for Android and iOS
React native: building shared components for Android and iOS
 
Notes (2012-06-08)
Notes (2012-06-08)Notes (2012-06-08)
Notes (2012-06-08)
 
MongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB StitchMongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
 
Huge web apps web expo 2013
Huge web apps web expo 2013Huge web apps web expo 2013
Huge web apps web expo 2013
 
Breaking the oracle tie
Breaking the oracle tieBreaking the oracle tie
Breaking the oracle tie
 
PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...PredictionIO - Building Applications That Predict User Behavior Through Big D...
PredictionIO - Building Applications That Predict User Behavior Through Big D...
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDB
 
Pre-Aggregated Analytics And Social Feeds Using MongoDB
Pre-Aggregated Analytics And Social Feeds Using MongoDBPre-Aggregated Analytics And Social Feeds Using MongoDB
Pre-Aggregated Analytics And Social Feeds Using MongoDB
 
From Monkey Coders To Smart Gorillas - Web Summit 2014
From Monkey Coders To Smart Gorillas - Web Summit 2014From Monkey Coders To Smart Gorillas - Web Summit 2014
From Monkey Coders To Smart Gorillas - Web Summit 2014
 
Rockin' the Web into the Next Dimension: JQueryTO 2014 Final Keynote
Rockin' the Web into the Next Dimension: JQueryTO 2014 Final KeynoteRockin' the Web into the Next Dimension: JQueryTO 2014 Final Keynote
Rockin' the Web into the Next Dimension: JQueryTO 2014 Final Keynote
 
Google Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talkGoogle Developer Group(GDG) DevFest Event 2012 Android talk
Google Developer Group(GDG) DevFest Event 2012 Android talk
 

Recently uploaded

Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
Peter Muessig
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
sjcobrien
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
Rakesh Kumar R
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
Peter Muessig
 
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
ssuserad3af4
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
Ayan Halder
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 

Recently uploaded (20)

Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
 
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 

Building complex UI on Android