Blog Infos
Author
Published
Topics
, , , ,
Published

Everything You Need to Know About Your First Android Project

Welcome to Android development! This guide will walk you through every file and folder in a new Android project, explaining what each piece does, how they connect, and where to write your code. Let’s dive in!

📁 THE BIG PICTURE: Project Overview
MyAndroidApp/                      ← Your project root
├── .gitignore                     ← Git ignore file
├── .gradle/                       ← Gradle's internal cache (don't touch!)
├── .idea/                         ← Android Studio settings (don't touch!)
├── .kotlin/                       ← Kotlin compiler cache (don't touch!)
├── app/                           ← YOUR MAIN CODE LIVES HERE! 🎯
├── build.gradle.kts               ← Project-level build config
├── gradle/                        ← Gradle wrapper + version catalog
├── gradle.properties              ← Gradle settings
├── gradlew                        ← Gradle wrapper script (Mac/Linux)
├── gradlew.bat                    ← Gradle wrapper script (Windows)
├── local.properties               ← Local machine config (don't commit!)
└── settings.gradle.kts            ← Project settings & modules

Think of an Android project like a company:

  • Root folder = The company headquarters
  • app/ = The main product team
  • gradle files = The operations/infrastructure team
  • build/ folders = The factory output (generated stuff)

 

🏗️ PART 1: ROOT-LEVEL FILES (The Foundation)
1. settings.gradle.kts – The Project Registry
pluginManagement {
    repositories {
        google { ... }           // Where Android libraries come from
        mavenCentral()           // Where most Java/Kotlin libraries come from
        gradlePluginPortal()     // Where Gradle plugins come from
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "MyAndroidApp"   // Your project name
include(":app")                        // Include the 'app' module

What it does:

  • Tells Gradle “here are all my modules” (right now just :app)
  • Defines WHERE to download libraries from (repositories)
  • Sets the project name In real-world apps, you’ll have MULTIPLE modules:
include(":app")
include(":core:network")
include(":core:database")
include(":feature:login")
include(":feature:home")

This is called modularization and it’s crucial for large apps.

what is a module? a module is a self-contained, independent pice of your code that can be developed, tested and even compile separately/ It’s like has LEGO blocks- each block (module) has its own purpose, but they all connect together to build something bigger. In Android Studio, when you created your project, you already have one module — the app module. That’s your main application module. But as apps grow, you can add more modules.

Why Bother with Modularization? (The Real Benefits)

  1. faster build times changing something in a specific module only requires rebuilding that module instead of the whole app.
  2. team scalability At big companies (Meta, Google), different teams own different modules. The chat team doesn’t need to know how the calling team implemented their features.
  3. clear boundaries and ownership
    this enforces architectire. A junior dev can’t accidentally create spaghetti dependencies
  4. Code Reusability write once use everywher
2. build.gradle.kts (Root Level) – The Master Build Config
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
    alias(libs.plugins.kotlin.compose) apply false
}
What are plugins?
Think of plugins like "Power-Ups" for your build system.
Gradle (your build system) by itself does'nt know how to:
Compile kotlin code
Build Android apks
handle jetpack compose

What it does:

  • Declares plugins available to ALL modules
  • apply false means “load but don’t activate here” (modules activate them individually)

Why alias(libs.plugins...)? This is the new Version Catalog system! Instead of writing versions everywhere, you define them once in gradle/libs.versions.toml.

 

3. gradle.properties – Gradle’s Settings
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
kotlin.code.style=official
android.nonTransitiveRClass=true

Line by line:

SettingWhat it meansorg.gradle.jvmargs=-Xmx2048mGive Gradle 2GB of RAM to work with
android.useAndroidX=trueUse modern AndroidX libraries (not old Support libraries)kotlin.code.style=official
Use JetBrains’ official Kotlin styleandroid.nonTransitiveRClass=trueEach module only sees its own resources (better for large projects)

When builds get slow, you can bump up the memory:

org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m
org.gradle.parallel=true
org.gradle.caching=true

 

4. gradle/libs.versions.toml – The Version Catalog (SUPER IMPORTANT!)
[versions]
agp = "8.11.2"                    # Android Gradle Plugin version
kotlin = "2.0.21"                  # Kotlin version
coreKtx = "1.17.0"                # Core KTX library version
composeBom = "2024.09.00"         # Compose Bill of Materials
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
# ... more libraries[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" 

Why this exists: Before version catalogs, you’d have versions scattered everywhere:

// OLD WAY - BAD! Versions everywhere!
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.compose.ui:ui:1.5.4")

Now you do:

// NEW WAY - GOOD! Single source of truth
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.ui)

The BOM (Bill of Materials) is MAGIC for Compose:

implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)  // No version needed!

The BOM ensures all Compose libraries are compatible versions. Trust me, version conflicts are a NIGHTMARE.

 

5. gradlew and gradlew.bat – The Gradle Wrapper

These are scripts that download and run the correct Gradle version.

Why it matters:

  • Your project says “I need Gradle 8.x”
  • The wrapper automatically downloads it
  • Everyone on the team uses the SAME Gradle version
  • No “works on my machine” problems!
./gradlew build     # On Mac/Linux
gradlew.bat build   # On Windows

 

6. local.properties – Your Machine’s Secrets
sdk.dir=/Users/yourname/Library/Android/sdk

⚠️ NEVER COMMIT THIS FILE! It contains paths specific to YOUR computer.

 

📱 PART 2: THE APP MODULE (Where the Magic Happens!)
app/
├── build.gradle.ktsApp-specific build config
├── proguard-rules.proCode obfuscation rules
├── src/
│   ├── main/                 ← Your main code
│   │   ├── AndroidManifest.xml
│   │   ├── java/             ← Kotlin/Java code (yes, even Kotlin goes here!)
│   │   └── res/              ← Resources (images, strings, layouts)
│   ├── test/                 ← Unit tests (run on JVM)
│   └── androidTest/          ← Instrumented tests (run on device/emulator)
└── build/                    ← Generated files (don't touch!)

 

7. app/build.gradle.kts – The App’s Build Recipe
plugins {
    alias(libs.plugins.android.application)  // "This is an Android app"
    alias(libs.plugins.kotlin.android)       // "Using Kotlin"
    alias(libs.plugins.kotlin.compose)       // "Using Jetpack Compose"
}
android {
    namespace = "com.example.myapp"           // Package name
    compileSdk = 36                            // API level to compile against    defaultConfig {
        applicationId = "com.example.myapp"        // Unique ID on Play Store
        minSdk = 24                                    // Oldest Android supported (7.0 Nougat)
        targetSdk = 36                                 // Newest Android targeted
        versionCode = 1                                // Internal version (must increase for updates)
        versionName = "1.0"                            // User-visible version
    }    buildTypes {
        release {
            isMinifyEnabled = false          // Should we shrink/obfuscate code?
            proguardFiles(...)               // Rules for ProGuard
        }
    }    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    
    kotlinOptions {
        jvmTarget = "11"
    }
    
    buildFeatures {
        compose = true                       // Enable Jetpack Compose!
    }
}dependencies {
    // IMPLEMENTATION - Code you use, included in the app
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    
    // The BOM manages all Compose versions
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.material3)
    
    // TEST - Only for unit tests
    testImplementation(libs.junit)
    
    // ANDROID TEST - Only for instrumented tests
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    
    // DEBUG - Only in debug builds
    debugImplementation(libs.androidx.ui.tooling)
}

Understanding SDK Versions:

┌─────────────────────────────────────────────────────────────┐
│  compileSdk = 36                                            │
│  (Use newest APIs for coding)                               │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  targetSdk = 36                                      │   │
│  │  (App is optimized for this Android version)         │   │
│  │                                                      │   │
│  │  ┌───────────────────────────────────────────────┐  │   │
│  │  │  minSdk = 24                                   │  │   │
│  │  │  (Oldest Android version your app runs on)     │  │   │
│  │  │  Android 7.0 Nougat (2016)                     │  │   │
│  │  └───────────────────────────────────────────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

Understanding dependency types is CRUCIAL:

implementationNeeded at runtime, internalMost libraries
apiNeeded at runtime, exposed to other modulesShared models
compileOnlyOnly needed at compile timeAnnotations
testImplementationOnly for unit testsJUnit, Mockito
androidTestImplementationOnly for device testsEspresso
debugImplementationOnly in debug buildsLeakCanary
releaseImplementationOnly in release buildsCrash reporting

 

8. AndroidManifest.xml – The App’s ID Card
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApp">
        
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.MyApp">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
    </application>
</manifest>

Key Parts Explained:

<manifest>Root element, contains package info
<application>App-wide settings (icon, theme, backup)
<activity>Declares a screen in your app
android:exported="true"Can this component be launched by other apps?<intent-filter>Declares what “intents” this activity responds toaction.MAIN + category.LAUNCHER“This is the app’s entry point, show it in the launcher!”

The manifest is where you declare:

  • Permissions: <uses-permission android:name="android.permission.INTERNET" />
  • Services: Background work
  • Broadcast Receivers: Listen for system events
  • Content Providers: Share data with other apps

 

📂 PART 3: JAVA/KOTLIN SOURCE CODE STRUCTURE
java/
└── com/
    └── example/
        └── myapp/                ← Your package (matches applicationId)
            ├── MainActivity.kt    ← Entry point
            └── ui/
                └── theme/
                    ├── Color.ktColor definitions
                    ├── Theme.kt     ← Theme configuration
                    ├── Type.kt      ← Typography
                    ├── UI/
                    │   └── ui.kt    ← Your UI components
                    └── viewmodel/
                        └── viewmodel.kt  ← ViewModel
9. MainActivity.kt – The Entry Point
package com.example.myapp
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import com.example.myapp.ui.theme.UI.Ui
import com.example.myapp.ui.theme.viewmodel.CounterViewModelclass MainActivity : ComponentActivity() {
    
    val viewmodel = CounterViewModel()   // Create the ViewModel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()               // Use the full screen
        setContent {                      // Set Compose UI as content
            Ui(viewmodel)
        }
    }
}

What’s happening:

  1. ComponentActivity – Base class for activities using Compose
  2. onCreate() – Called when the activity is created (app launch)
  3. savedInstanceState – Android’s way of saving state during config changes (rotation)
  4. setContent { } – “Here’s my Compose UI!”

There’s a PROBLEM in this code!

val viewmodel = Counterviewmodel()  // ❌ BAD! Gets destroyed on rotation!

The proper way:

val viewmodel: CounterViewModel by viewModels()  // ✅ Survives rotation!

 

10. The UI Theme Files (Material Design System)
Color.kt – Your Color Palette
package com.example.myapp.ui.theme
import androidx.compose.ui.graphics.Colorval Purple80 = Color(0xFFD0BCFF)    // Light theme primary
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)val Purple40 = Color(0xFF6650a4)    // Dark theme primary
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)

Why separate? Material Design has light AND dark themes. 80 suffix = light, 40 = dark.

Type.kt – Typography (Font Styles)
val Typography = Typography(
    bodyLarge = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 16.sp,
        lineHeight = 24.sp,
        letterSpacing = 0.5.sp
    )
    // titleLarge, labelSmall, etc.
)

What is sp? Scale-independent Pixels – like dp but respects user’s font size settings!

Theme.kt – Putting It All Together
@Composable
fun MyAppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context) 
            else dynamicLightColorScheme(context)
        }
        darkTheme -> DarkColorScheme
        else -> LightColorScheme
    }
    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography,
        content = content
    )
}

Dynamic Color = On Android 12+, colors can match user’s wallpaper!

 

11. Understanding ViewModel
package com.example.myapp.ui.theme.viewmodel
import androidx.lifecycle.ViewModelclass CounterViewModel: ViewModel() {
    val counter: Int = 7
}

What is a ViewModel?

  • Holds UI data
  • Survives configuration changes (screen rotation)
  • Lives as long as the scope it’s attached to (Activity/Fragment)
┌─────────────────────────────────────────────────────────────┐
│                    Activity Lifecycle                        │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐            │
│  │ Created  │ ──► │ Rotated  │ ──► │Destroyed │            │
│  │          │     │(recreate)│     │          │            │
│  └──────────┘     └──────────┘     └──────────┘            │
│       │                │                 │                  │
│       ▼                ▼                 ▼                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              ViewModel (SURVIVES!)                   │   │
│  │              Created ─────────────────► Destroyed    │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

 

12. The UI Composable
@Composable
fun Ui(vm: Counterviewmodel){
    val count = vm.counter
    var count1 by rememberSaveable { mutableStateOf(0) }
    
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center){
        Column {
            Text(text = "The count is $count")
            Button(onClick = { count1 = clicking(count1) }) {
                Text("Increase Count")
            }
            Text(text = "The count1 is $count1")
        }
    }
}

State in Compose:

TypeSurvives RecompositionSurvives Config Changeremember✅❌rememberSaveable✅✅ViewModel✅✅

 

📦 PART 4: RESOURCES FOLDER (res/)
res/
├── drawable/                  ← Vector graphics, shapes
│   ├── ic_launcher_background.xml
│   └── ic_launcher_foreground.xml
├── mipmap-hdpi/              ← App icons (high density)
├── mipmap-mdpi/              ← App icons (medium density)
├── mipmap-xhdpi/             ← App icons (extra high)
├── mipmap-xxhdpi/            ← App icons (extra extra high)
├── mipmap-xxxhdpi/           ← App icons (extra extra extra high)
├── mipmap-anydpi-v26/        ← Adaptive icons (Android 8+)
├── values/
│   ├── colors.xml            ← Color resources
│   ├── strings.xml           ← Text strings
│   └── themes.xml            ← XML themes
└── xml/
    ├── backup_rules.xml      ← What to backup to cloud
    └── data_extraction_rules.xml
Understanding Density Buckets

BucketDensityScaleExample Devicemdpi160 dpi1xBaselinehdpi240 dpi1.5xOld phonesxhdpi320 dpi2xMost phonesxxhdpi480 dpi3xHigh-end phonesxxxhdpi640 dpi4xFlagship phones

For app icons, always provide all densities. For other images, use vectors (SVG-like) when possible — they scale perfectly!

strings.xml – Never Hardcode Strings!
<resources>
    <string name="app_name">MyApp</string>
</resources>

Why?

  1. Localization: Easy to translate
  2. Consistency: Change once, updates everywhere
  3. Play Store Requirement: For global apps
// ❌ BAD
Text("Hello World")
// ✅ GOOD
Text(stringResource(R.string.hello_world))

 

🔗 PART 5: HOW EVERYTHING CONNECTS
┌─────────────────────────────────────────────────────────────────────────┐
│                              BUILD SYSTEM                                │
│  settings.gradle.kts → "Include :app module"                            │
│         │                                                               │
│         ▼                                                               │
│  build.gradle.kts (root) → "Here are available plugins"                 │
│         │                                                               │
│         ▼                                                               │
│  libs.versions.toml → "Here are all library versions"                   │
│         │                                                               │
│         ▼                                                               │
│  app/build.gradle.kts → "I'm an Android app using these dependencies"  │
└─────────────────────────────────────────────────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                              RUNTIME                                     │
│  AndroidManifest.xml → "MainActivity is the entry point"                │
│         │                                                               │
│         ▼                                                               │
│  MainActivity.kt → onCreate() → setContent { Ui(viewmodel) }            │
│         │                                                               │
│         ▼                                                               │
│  Theme.kt → MaterialTheme wraps your content                            │
│         │                                                               │
│         ▼                                                               │
│  ui.kt → Your actual UI composables                                     │
│         │                                                               │
│         ▼                                                               │
│  viewmodel.kt → Holds your data/state                                   │
└─────────────────────────────────────────────────────────────────────────┘

 

🏢 PART 6: RECOMMENDED PROJECT STRUCTURE (Real World)
app/src/main/java/com/yourcompany/app/
├── MainActivity.kt
├── MyApplication.kt              ← Application class for initialization
│
├── data/                         ← DATA LAYER
│   ├── local/                    ← Local database
│   │   ├── AppDatabase.kt
│   │   ├── dao/
│   │   │   └── UserDao.kt
│   │   └── entity/
│   │       └── UserEntity.kt
│   ├── remote/                   ← Network/API
│   │   ├── ApiService.kt
│   │   └── dto/
│   │       └── UserDto.kt
│   └── repository/               ← Data sources combination
│       └── UserRepository.kt
│
├── domain/                       ← DOMAIN LAYER (Business Logic)
│   ├── model/
│   │   └── User.kt               ← Clean domain models
│   └── usecase/
│       └── GetUserUseCase.kt
│
├── presentation/                 ← PRESENTATION LAYER (UI)
│   ├── navigation/
│   │   └── NavGraph.kt
│   ├── common/
│   │   └── components/           ← Reusable UI components
│   │       └── LoadingSpinner.kt
│   └── feature/
│       ├── home/
│       │   ├── HomeScreen.kt
│       │   └── HomeViewModel.kt
│       └── profile/
│           ├── ProfileScreen.kt
│           └── ProfileViewModel.kt
│
├── di/                           ← Dependency Injection
│   └── AppModule.kt
│
└── util/                         ← Utilities
    └── Extensions.kt

 

💡 PART 7: WHICH FILE FOR WHAT? (Decision Guide)
  • Add a new screenCreate in presentation/feature/
  • Add a new network calldata/remote/ApiService.kt
  • Save data locallydata/local/ with Room database
  • Add a reusable buttonpresentation/common/components/
  • Add app-wide colorsui/theme/Color.kt
  • Add a new stringres/values/strings.xml
  • Add an imageres/drawable/ (vector) or res/mipmap-*/
  • Request a permissionAndroidManifest.xml
  • Change app iconres/mipmap-*/ folders
  • Add a new libraryapp/build.gradle.kts in dependencies
  • Add a background service
  • Create Service class + register in Manifest

 

🚨 PART 8: BEST PRACTICES & GOLDEN RULES
1. Never Touch build/ Folders

Everything in there is generated. Delete it if builds break (or run ./gradlew clean).

2. Always Use Version Catalogs

Keep all versions in libs.versions.toml. Your future self will thank you.

3. Commit .gitignore Properly
# These should be ignored:
*.iml
.gradle/
/local.properties
/.idea/
/build/
/app/build/
4. Understand the Build Variants
buildTypes {
    debug { }      // For development
    release { }    // For production
}
productFlavors {
    dev { }        // Dev environment
    staging { }    // Test environment  
    prod { }       // Production
}
// Results in: devDebug, devRelease, stagingDebug, stagingRelease, prodDebug, prodRelease
5. Resources are Magic

Android automatically picks the right resource:

  • values/ → Default
  • values-es/ → Spanish
  • values-night/ → Dark mode
  • drawable-xxhdpi/ → High DPI screens
6. The R Class is Your Friend

Android generates R.java with references to all resources:

R.string.app_name    // String resource
R.drawable.icon      // Image resource
R.color.primary      // Color resource
R.id.button_submit   // View ID

 

🎓 QUICK REFERENCE CARD
┌────────────────────────────────────────────────────────────────┐
│                    ANDROID PROJECT CHEAT SHEET                  │
├────────────────────────────────────────────────────────────────┤
│ BUILD SYSTEM                                                    │
│   settings.gradle.kts  → Module registration                   │
│   build.gradle.kts     → Plugins & dependencies                │
│   gradle.properties    → Gradle settings                       │
│   libs.versions.toml   → Version management                    │
├────────────────────────────────────────────────────────────────┤
│ APP CONFIGURATION                                              │
│   AndroidManifest.xml  → App identity & components             │
│   proguard-rules.pro   → Code obfuscation rules               │
├────────────────────────────────────────────────────────────────┤
│ SOURCE CODE (java/)                                            │
│   *Activity.kt         → Screen/Entry points                   │
│   *ViewModel.kt        → UI state holders                      │
│   *Screen.kt           → Composable screens                    │
│   *Repository.kt       → Data sources                          │
├────────────────────────────────────────────────────────────────┤
│ RESOURCES (res/)                                               │
│   drawable/            → Vector graphics                       │
│   mipmap-*/            → App icons                             │
│   values/strings.xml   → Text strings                          │
│   values/colors.xml    → Color definitions                     │
│   values/themes.xml    → XML themes                            │
│   xml/                 → Configuration files                   │
└────────────────────────────────────────────────────────────────┘

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Kobweb:Creating websites in Kotlin leveraging Compose HTML

Kobweb is a Kotlin web framework that aims to make web development enjoyable by building on top of Compose HTML and drawing inspiration from Jetpack Compose.
Watch Video

Kobweb:Creating websites in Kotlin leveraging Compose HTML

David Herman
Ex-Googler, author of Kobweb

Kobweb:Creating websites in Kotlin leveraging Compose HTML

David Herman
Ex-Googler, author o ...

Kobweb:Creating websites in Kotlin leveraging Compose HTML

David Herman
Ex-Googler, author of Kob ...

Jobs

🎯 YOUR NEXT STEPS
  1. Run the app — See it working!
  2. Modify strings.xml — Change the app name
  3. Add a new color — Use it in your composable
  4. Create a new screen — Practice the pattern
  5. Add a dependency — Try adding a new library

Welcome to Android development! It’s a deep field with lots to learn, but let’s take it step by step.

This article was previously published on proandroiddev.com

Menu