├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── themes.xml
│ │ │ │ └── colors.xml
│ │ │ ├── drawable
│ │ │ │ ├── living_room.png
│ │ │ │ ├── wi_fi_icon.xml
│ │ │ │ ├── ic_launcher_foreground.xml
│ │ │ │ ├── snowflake.xml
│ │ │ │ ├── cutlery.xml
│ │ │ │ ├── bed.xml
│ │ │ │ ├── television.xml
│ │ │ │ ├── pawprint.xml
│ │ │ │ ├── serving_dish.xml
│ │ │ │ ├── android.xml
│ │ │ │ ├── breakfast.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ └── xml
│ │ │ │ ├── backup_rules.xml
│ │ │ │ └── data_extraction_rules.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── samplecomposeapp
│ │ │ │ ├── ui_practice
│ │ │ │ ├── list
│ │ │ │ │ ├── ToolsViewState.kt
│ │ │ │ │ ├── model
│ │ │ │ │ │ └── Person.kt
│ │ │ │ │ ├── ToolsView.kt
│ │ │ │ │ ├── repository
│ │ │ │ │ │ └── PersonRepository.kt
│ │ │ │ │ ├── lazyColumn
│ │ │ │ │ │ ├── LazyColumn.kt
│ │ │ │ │ │ └── LazyColumnPractice.kt
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── CustomItem.kt
│ │ │ │ │ ├── lazyGrid
│ │ │ │ │ │ └── LazyGridDemo.kt
│ │ │ │ │ └── ListPractice.kt
│ │ │ │ ├── navigation
│ │ │ │ │ ├── navgraph
│ │ │ │ │ │ ├── NavGraphScreen.kt
│ │ │ │ │ │ ├── AuthNavGraph.kt
│ │ │ │ │ │ └── HomeNavGraph.kt
│ │ │ │ │ ├── Screen.kt
│ │ │ │ │ └── screens
│ │ │ │ │ │ ├── SignUpScreen.kt
│ │ │ │ │ │ ├── DetailScreen.kt
│ │ │ │ │ │ ├── LoginScreen.kt
│ │ │ │ │ │ └── HomeScreen.kt
│ │ │ │ ├── textview
│ │ │ │ │ ├── BoxComposable.kt
│ │ │ │ │ ├── SubScriptAndSuperScript.kt
│ │ │ │ │ ├── TextComposable.kt
│ │ │ │ │ └── ExpandableCard.kt
│ │ │ │ ├── imageview
│ │ │ │ │ └── ImageViewPractice.kt
│ │ │ │ ├── buttons
│ │ │ │ │ └── GradientButton.kt
│ │ │ │ ├── layouts
│ │ │ │ │ ├── BoxPractice.kt
│ │ │ │ │ ├── FlowLayout.kt
│ │ │ │ │ ├── RowColumnDemo.kt
│ │ │ │ │ └── Scaffold.kt
│ │ │ │ ├── textField
│ │ │ │ │ ├── CharacterCountTextField.kt
│ │ │ │ │ ├── PasswordInputField.kt
│ │ │ │ │ ├── TextFieldCompose.kt
│ │ │ │ │ └── GoogleSignUpButton.kt
│ │ │ │ ├── windowSizeClass
│ │ │ │ │ └── WindowSizeClassDemo.kt
│ │ │ │ └── PracticeScreens
│ │ │ │ │ └── AssignmentScreen.kt
│ │ │ │ ├── ConnectivityObserver.kt
│ │ │ │ ├── statemanagement
│ │ │ │ ├── number_guess
│ │ │ │ │ ├── NumberGuessState.kt
│ │ │ │ │ ├── NumberGuessAction.kt
│ │ │ │ │ ├── NumberGuessViewModel.kt
│ │ │ │ │ └── StateManagementGame.kt
│ │ │ │ ├── todo_list_check
│ │ │ │ │ ├── TodoListState.kt
│ │ │ │ │ ├── TodoListActions.kt
│ │ │ │ │ └── TodoListViewModel.kt
│ │ │ │ ├── StateHoistingPractice.kt
│ │ │ │ └── StatePractice.kt
│ │ │ │ ├── ui
│ │ │ │ └── theme
│ │ │ │ │ ├── Color.kt
│ │ │ │ │ ├── Type.kt
│ │ │ │ │ └── Theme.kt
│ │ │ │ ├── ConnectivityViewModel.kt
│ │ │ │ ├── modifiers
│ │ │ │ ├── OffsetModifierPractice.kt
│ │ │ │ ├── ModifierPractice.kt
│ │ │ │ ├── ClickableModifierPractice.kt
│ │ │ │ ├── SpacingModifierPractice.kt
│ │ │ │ ├── ShapeModifierPractice.kt
│ │ │ │ └── FocusManagementPractice.kt
│ │ │ │ ├── CoilImageLoading.kt
│ │ │ │ └── AndroidConnectivityObserver.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── samplecomposeapp
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── samplecomposeapp
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle.kts
├── .idea
├── .gitignore
├── codeStyles
│ ├── codeStyleConfig.xml
│ └── Project.xml
├── compiler.xml
├── kotlinc.xml
├── vcs.xml
├── valkyrie_settings.xml
├── migrations.xml
├── misc.xml
├── gradle.xml
├── runConfigurations.xml
├── deploymentTargetSelector.xml
└── inspectionProfiles
│ └── Project_Default.xml
├── gradle
├── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── libs.versions.toml
├── Gemfile
├── fastlane
├── Appfile
├── Pluginfile
├── report.xml
├── README.md
└── Fastfile
├── .gitignore
├── settings.gradle.kts
├── .github
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── SECURITY.md
├── CONTRIBUTING.md
├── gradle.properties
├── gradlew.bat
├── README.md
├── CODE_OF_CONDUCT.md
├── gradlew
└── Gemfile.lock
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SampleComposeApp
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable/living_room.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/drawable/living_room.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SardarKhan299/PracticeComposeComponents/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
4 |
5 | plugins_path = File.join(File.dirname(__FILE__), '.', 'Pluginfile')
6 | eval_gemfile(plugins_path) if File.exist?(plugins_path)
7 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | json_key_file("sardar") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
2 | package_name("com.example.samplecomposeapp") # e.g. com.krausefx.app
3 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/ToolsViewState.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list
2 |
3 | data class ToolsViewState (
4 | val isLoading: Boolean = false,
5 | )
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ConnectivityObserver.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp
2 |
3 | import kotlinx.coroutines.flow.Flow
4 |
5 | interface ConnectivityObserver {
6 | val isConnected: Flow
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/model/Person.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list.model
2 |
3 | data class Person(
4 | val id:Int,
5 | val firstName: String,
6 | val lastName: String,
7 | val age: Int
8 | )
--------------------------------------------------------------------------------
/fastlane/Pluginfile:
--------------------------------------------------------------------------------
1 | # Autogenerated by fastlane
2 | #
3 | # Ensure this file is checked in to source control!
4 |
5 | gem 'fastlane-plugin-firebase_app_distribution'
6 | gem 'fastlane-plugin-firebase_app_distribution'
7 | gem 'fastlane-plugin-firebase_app_distribution'
8 |
--------------------------------------------------------------------------------
/.idea/valkyrie_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Nov 16 16:23:04 PKT 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/number_guess/NumberGuessState.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement.number_guess
2 |
3 | data class NumberGuessState(
4 | val numberText: String = "",
5 | val guessText: String? = "",
6 | val isGuessCorrect: Boolean = false
7 | )
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/number_guess/NumberGuessAction.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement.number_guess
2 |
3 | sealed interface NumberGuessAction {
4 | data object OnGuessClick: NumberGuessAction
5 | data class OnNumberTextChange(val newNumberText: String): NumberGuessAction
6 | data object OnStartNewGameButton: NumberGuessAction
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | val Purple80 = Color(0xFFD0BCFF)
6 | val PurpleGrey80 = Color(0xFFCCC2DC)
7 | val Pink80 = Color(0xFFEFB8C8)
8 |
9 | val Purple40 = Color(0xFF6650a4)
10 | val PurpleGrey40 = Color(0xFF625b71)
11 | val Pink40 = Color(0xFF7D5260)
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/todo_list_check/TodoListState.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement.todo_list_check
2 |
3 | import java.util.UUID
4 |
5 | data class TodoListState (
6 | val id: String = UUID.randomUUID().toString(),
7 | val title: String ="",
8 | val description: String="",
9 | val isChecked: Boolean = false,
10 | val isDeleted: Boolean = false
11 | )
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/fastlane/report.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/samplecomposeapp/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp
2 |
3 | import org.junit.Assert.assertEquals
4 | import org.junit.Test
5 |
6 | /**
7 | * Example local unit test, which will execute on the development machine (host).
8 | *
9 | * See [testing documentation](http://d.android.com/tools/testing).
10 | */
11 | class ExampleUnitTest {
12 | @Test
13 | fun addition_isCorrect() {
14 | assertEquals(4, 2 + 2)
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/todo_list_check/TodoListActions.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement.todo_list_check
2 |
3 | import com.example.samplecomposeapp.statemanagement.number_guess.NumberGuessAction
4 |
5 | sealed interface TodoListActions {
6 | data class OnCheckedClick(val id: String): TodoListActions
7 | data class OnDeleteClick(val id: String): TodoListActions
8 | data class OnAddItemClicked(val title: String,val desc: String): TodoListActions
9 | }
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ConnectivityViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.viewModelScope
5 | import kotlinx.coroutines.flow.SharingStarted
6 | import kotlinx.coroutines.flow.stateIn
7 |
8 | class ConnectivityViewModel(private val connectivityObserver: ConnectivityObserver) : ViewModel() {
9 | private val _isConnected = connectivityObserver.isConnected
10 | .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), false)
11 | val isConnected = _isConnected
12 | }
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google {
4 | content {
5 | includeGroupByRegex("com\\.android.*")
6 | includeGroupByRegex("com\\.google.*")
7 | includeGroupByRegex("androidx.*")
8 | }
9 | }
10 | mavenCentral()
11 | gradlePluginPortal()
12 | }
13 | }
14 | dependencyResolutionManagement {
15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
16 | repositories {
17 | google()
18 | mavenCentral()
19 | }
20 | }
21 |
22 | rootProject.name = "SampleComposeApp"
23 | include(":app")
24 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ------- | ------------------ |
10 | | 5.1.x | :white_check_mark: |
11 | | 5.0.x | :x: |
12 | | 4.0.x | :white_check_mark: |
13 | | < 4.0 | :x: |
14 |
15 | ## Reporting a Vulnerability
16 |
17 | Use this section to tell people how to report a vulnerability.
18 |
19 | Tell them where to go, how often they can expect to get an update on a
20 | reported vulnerability, what to expect if the vulnerability is accepted or
21 | declined, etc.
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/navgraph/NavGraphScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation.navgraph
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.navigation.NavHostController
5 | import androidx.navigation.compose.NavHost
6 | import com.example.samplecomposeapp.ui_practice.navigation.HOME_ROUTE
7 | import com.example.samplecomposeapp.ui_practice.navigation.ROOT_ROUTE
8 |
9 | @Composable
10 | fun SetupNavGraph(navController: NavHostController) {
11 | NavHost(
12 | navController = navController,
13 | startDestination = HOME_ROUTE,
14 | route = ROOT_ROUTE
15 | ) {
16 | homeNavGraph(navController)
17 | authNavGraph(navController)
18 | }
19 |
20 |
21 | }
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/samplecomposeapp/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp
2 |
3 | import androidx.test.ext.junit.runners.AndroidJUnit4
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import org.junit.Assert.assertEquals
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | /**
10 | * Instrumented test, which will execute on an Android device.
11 | *
12 | * See [testing documentation](http://d.android.com/tools/testing).
13 | */
14 | @RunWith(AndroidJUnit4::class)
15 | class ExampleInstrumentedTest {
16 | @Test
17 | fun useAppContext() {
18 | // Context of the app under test.
19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
20 | assertEquals("com.example.samplecomposeapp", appContext.packageName)
21 | }
22 | }
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## 🌱 **How to Contribute**
2 |
3 | Contributions are welcome! Follow these steps to make your contributions:
4 |
5 | 1. **Fork the Repository:**
6 | Click the **Fork** button on the top right of this repository.
7 |
8 | 2. **Create a New Branch:**
9 | ```bash
10 | git checkout -b feature-name
11 | ```
12 |
13 | 3. **Make Changes:**
14 | - Add a new Jetpack Compose component or improve existing ones.
15 | - Ensure your code follows Kotlin and Compose best practices.
16 |
17 | 4. **Commit and Push:**
18 | ```bash
19 | git add .
20 | git commit -m "Added new Compose component: XYZ"
21 | git push origin feature-name
22 | ```
23 |
24 | 5. **Create a Pull Request:**
25 | - Go to your forked repository on GitHub.
26 | - Click the **Compare & Pull Request** button and explain your changes.
27 |
28 | ---
29 |
--------------------------------------------------------------------------------
/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ----
3 |
4 | # Installation
5 |
6 | Make sure you have the latest version of the Xcode command line tools installed:
7 |
8 | ```sh
9 | xcode-select --install
10 | ```
11 |
12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
13 |
14 | # Available Actions
15 |
16 | ## Android
17 |
18 | ### android release
19 |
20 | ```sh
21 | [bundle exec] fastlane android release
22 | ```
23 |
24 | Build and upload APK to Firebase App Distribution
25 |
26 | ----
27 |
28 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
29 |
30 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
31 |
32 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/Screen.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation
2 |
3 | const val DETAIL_ARGUMENT_KEY = "id"
4 | const val DETAIL_ARGUMENT_KEY2 = "name"
5 | const val AUTHENTICATION_ROUTE = "authentication"
6 | const val ROOT_ROUTE = "root"
7 | const val HOME_ROUTE = "home"
8 |
9 | sealed class Screen(val route: String){
10 | object Home: Screen(route = "home_screen")
11 | object Detail: Screen(route = "detail_screen/{$DETAIL_ARGUMENT_KEY}/{$DETAIL_ARGUMENT_KEY2}"){
12 | fun passId(id: Int): String{
13 | return this.route.replace(oldValue = "{$DETAIL_ARGUMENT_KEY}", newValue = id.toString())
14 | }
15 | fun passIdAndName(id: Int, name:String): String{
16 | return "detail_screen/$id/$name"
17 | }
18 | }
19 |
20 | object Login: Screen(route = "login_screen")
21 | object SignUp: Screen(route = "signup_screen")
22 |
23 | }
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/navgraph/AuthNavGraph.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation.navgraph
2 |
3 | import androidx.navigation.NavGraphBuilder
4 | import androidx.navigation.NavHostController
5 | import androidx.navigation.compose.composable
6 | import androidx.navigation.navigation
7 | import com.example.samplecomposeapp.ui_practice.navigation.AUTHENTICATION_ROUTE
8 | import com.example.samplecomposeapp.ui_practice.navigation.Screen
9 | import com.example.samplecomposeapp.ui_practice.navigation.screens.LoginScreen
10 | import com.example.samplecomposeapp.ui_practice.navigation.screens.SignUpScreen
11 |
12 |
13 | // Auth Navigation Graph...//
14 | fun NavGraphBuilder.authNavGraph(navController: NavHostController){
15 | navigation(
16 | startDestination = Screen.Login.route,
17 | route = AUTHENTICATION_ROUTE
18 | ){
19 | composable(
20 | route = Screen.Login.route
21 | ) {
22 | LoginScreen(navController)
23 | }
24 |
25 | composable(
26 | route = Screen.SignUp.route
27 | ) {
28 | SignUpScreen(navController)
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/screens/SignUpScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation.screens
2 |
3 | import androidx.compose.foundation.clickable
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.material3.MaterialTheme
7 | import androidx.compose.material3.Text
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Alignment
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.text.font.FontWeight
12 | import androidx.navigation.NavController
13 |
14 | @Composable
15 | fun SignUpScreen(navController: NavController) {
16 |
17 | Box(
18 | modifier = Modifier.fillMaxSize(),
19 | contentAlignment = Alignment.Center
20 | ){
21 | Text(
22 | modifier = Modifier.clickable {
23 | navController.popBackStack()
24 | },
25 | text = "SignUp Screen",
26 | color = MaterialTheme.colorScheme.primary,
27 | fontSize = MaterialTheme.typography.headlineLarge.fontSize,
28 | fontWeight = FontWeight.Bold
29 | )
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/ToolsView.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list
2 |
3 | import android.content.res.Configuration
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.material3.MaterialTheme
7 | import androidx.compose.material3.Scaffold
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.tooling.preview.Preview
11 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
12 |
13 | @Composable
14 | fun ToolsView(modifier: Modifier = Modifier,
15 | state: ToolsViewState){
16 | Scaffold(modifier= modifier ,
17 | contentColor = MaterialTheme.colorScheme.primary) {
18 | paddingValues ->
19 | Column(modifier = Modifier.padding(paddingValues)){
20 |
21 | }
22 | }
23 |
24 |
25 | }
26 |
27 |
28 | @Preview("Light")
29 | @Preview("Dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
30 | @Composable
31 | private fun PreViewTools(){
32 | SampleComposeAppTheme {
33 | ToolsView(state = ToolsViewState())
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/repository/PersonRepository.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list.repository
2 |
3 |
4 | import com.example.samplecomposeapp.ui_practice.list.model.Person
5 |
6 | class PersonRepository {
7 |
8 | fun getAllData():List{
9 | return listOf(
10 | Person(id = 0,
11 | firstName = "John",
12 | lastName = "Doe",
13 | age = 21),
14 |
15 | Person(id = 1,
16 | firstName = "Mrunal",
17 | lastName = "Haris",
18 | age = 23),
19 | Person(id = 2,
20 | firstName = "Hyshal",
21 | lastName = "Doe",
22 | age = 30),
23 | Person(id = 3,
24 | firstName = "Ahmed",
25 | lastName = "John",
26 | age = 29),
27 | Person(id = 4,
28 | firstName = "Michal",
29 | lastName = "Doe",
30 | age = 31),
31 | Person(id = 5,
32 | firstName = "Maria",
33 | lastName = "Doe",
34 | age = 34)
35 | )
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui.theme
2 |
3 | import androidx.compose.material3.Typography
4 | import androidx.compose.ui.text.TextStyle
5 | import androidx.compose.ui.text.font.FontFamily
6 | import androidx.compose.ui.text.font.FontWeight
7 | import androidx.compose.ui.unit.sp
8 |
9 | // Set of Material typography styles to start with
10 | val Typography = Typography(
11 | bodyLarge = TextStyle(
12 | fontFamily = FontFamily.Default,
13 | fontWeight = FontWeight.Normal,
14 | fontSize = 16.sp,
15 | lineHeight = 24.sp,
16 | letterSpacing = 0.5.sp
17 | ),
18 | headlineMedium = TextStyle(
19 | fontFamily = FontFamily.Default,
20 | fontWeight = FontWeight.ExtraBold,
21 | fontSize = 34.sp
22 | )
23 | /* Other default text styles to override
24 | titleLarge = TextStyle(
25 | fontFamily = FontFamily.Default,
26 | fontWeight = FontWeight.Normal,
27 | fontSize = 22.sp,
28 | lineHeight = 28.sp,
29 | letterSpacing = 0.sp
30 | ),
31 | labelSmall = TextStyle(
32 | fontFamily = FontFamily.Default,
33 | fontWeight = FontWeight.Medium,
34 | fontSize = 11.sp,
35 | lineHeight = 16.sp,
36 | letterSpacing = 0.5.sp
37 | )
38 | */
39 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/modifiers/OffsetModifierPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.modifiers
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.offset
6 | import androidx.compose.foundation.layout.size
7 | import androidx.compose.material3.Text
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.graphics.Color
11 | import androidx.compose.ui.tooling.preview.Preview
12 | import androidx.compose.ui.unit.dp
13 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
14 |
15 | @Composable
16 | fun OffsetModifierPractice(modifier: Modifier = Modifier) {
17 | Column (
18 | modifier = Modifier.size(200.dp)
19 | .background(Color.Red)
20 | .offset(
21 | x = 50.dp,
22 | y = 20.dp
23 | )
24 | ){
25 |
26 | Text(text ="Testing Text",
27 | modifier = modifier
28 | .background(Color.Blue)
29 | .offset(x = 10.dp,
30 | y = 2.dp)
31 | )
32 |
33 | Text(text ="Testing Text2",
34 | modifier = modifier.background(Color.Yellow)
35 | )
36 | }
37 | }
38 |
39 | @Preview
40 | @Composable
41 | private fun OffsetModifierPracticePrev() {
42 | SampleComposeAppTheme {
43 | OffsetModifierPractice()
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/screens/DetailScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation.screens
2 |
3 | import androidx.compose.foundation.clickable
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.material3.MaterialTheme
7 | import androidx.compose.material3.Text
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Alignment
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.text.font.FontWeight
12 | import androidx.compose.ui.tooling.preview.Preview
13 | import androidx.navigation.NavController
14 | import androidx.navigation.compose.rememberNavController
15 |
16 | @Composable
17 | fun DetailScreen(navController: NavController) {
18 | Box(
19 | modifier = Modifier.fillMaxSize(),
20 | contentAlignment = Alignment.Center
21 | ){
22 | Text(
23 | modifier = Modifier.clickable {
24 | navController.popBackStack()
25 | },
26 | text = "Detail",
27 | color = MaterialTheme.colorScheme.secondary,
28 | fontSize = MaterialTheme.typography.headlineLarge.fontSize,
29 | fontWeight = FontWeight.Bold
30 | )
31 | }
32 | }
33 |
34 |
35 | @Preview(showBackground = true)
36 | @Composable
37 | private fun HomeScreenPreview() {
38 | DetailScreen(rememberNavController())
39 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. For more details, visit
12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | # This file contains the fastlane.tools configuration
2 | # You can find the documentation at https://docs.fastlane.tools
3 | #
4 | # For a list of all available actions, check out
5 | #
6 | # https://docs.fastlane.tools/actions
7 | #
8 | # For a list of all available plugins, check out
9 | #
10 | # https://docs.fastlane.tools/plugins/available-plugins
11 | #
12 |
13 | # Uncomment the line if you want fastlane to automatically update itself
14 | # update_fastlane
15 |
16 | default_platform(:android)
17 |
18 | platform :android do
19 | desc "Build and upload APK to Firebase App Distribution"
20 | lane :release do
21 | # Build APK (optional, if you haven't already built it)
22 | gradle(
23 | task: "assemble",
24 | build_type: "Release"
25 | )
26 |
27 | # Upload the APK to Firebase App Distribution
28 | release = firebase_app_distribution(
29 | app: "1:770513751971:android:629b84357dbb33ac069416", # Your Firebase app ID
30 | firebase_cli_token: "your_firebase_cli_token", # Your Firebase CLI token
31 | service_credentials_file: "/Users/sardarkhan/Downloads",
32 | groups: "tester", # The group(s) of testers you want to distribute to
33 | apk_path: "./app/build/outputs/apk/release/app-release.apk", # Path to the APK
34 | release_notes: "This is a release note for the new build." # Release notes (optional)
35 | )
36 | end
37 | end
--------------------------------------------------------------------------------
/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wi_fi_icon.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textview/BoxComposable.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textview
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.foundation.rememberScrollState
10 | import androidx.compose.foundation.verticalScroll
11 | import androidx.compose.material3.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Alignment
14 | import androidx.compose.ui.Modifier
15 | import androidx.compose.ui.graphics.Color
16 | import androidx.compose.ui.unit.dp
17 | import androidx.compose.ui.unit.sp
18 |
19 | @Composable
20 | fun BoxPractice() {
21 | Box(
22 | modifier = Modifier.fillMaxSize(),
23 | contentAlignment = Alignment.TopCenter
24 | ) {
25 | Box(
26 | modifier = Modifier
27 | .background(Color.Blue)
28 | .padding(12.dp)
29 | .verticalScroll(rememberScrollState()),
30 | contentAlignment = Alignment.Center
31 | ) {
32 | Box(
33 | modifier = Modifier
34 | .background(Color.Red)
35 | .width(40.dp)
36 | .height(40.dp)
37 | )
38 | Text(text = "I love Android", fontSize = 45.sp)
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/modifiers/ModifierPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.modifiers
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.foundation.layout.size
7 | import androidx.compose.foundation.shape.CircleShape
8 | import androidx.compose.material3.Text
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Alignment
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.draw.clip
13 | import androidx.compose.ui.graphics.Color
14 | import androidx.compose.ui.tooling.preview.Preview
15 | import androidx.compose.ui.unit.dp
16 | import com.example.samplecomposeapp.statemanagement.todo_list_check.TodoListScreen
17 | import com.example.samplecomposeapp.statemanagement.todo_list_check.TodoListState
18 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
19 |
20 | @Composable
21 | fun ModifierPractice(modifier: Modifier = Modifier) {
22 | Box(
23 | modifier = Modifier
24 | .size(100.dp)
25 | .background(Color.Yellow)
26 | .clip(CircleShape)
27 | .background(Color.Red)
28 | .padding(8.dp)
29 | .clip(CircleShape)
30 | .background(Color.Blue)
31 | , contentAlignment = Alignment.Center
32 | ) {
33 | Text(
34 | text = "Hello World."
35 | )
36 | }
37 | }
38 |
39 |
40 | @Preview(showBackground = true)
41 | @Composable
42 | private fun ModifierPracticePrev() {
43 | SampleComposeAppTheme {
44 | ModifierPractice()
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/CoilImageLoading.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp
2 |
3 | import androidx.compose.foundation.layout.Box
4 | import androidx.compose.foundation.layout.height
5 | import androidx.compose.foundation.layout.width
6 | import androidx.compose.foundation.shape.CircleShape
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.ui.Alignment
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.draw.clip
11 | import androidx.compose.ui.layout.ContentScale
12 | import androidx.compose.ui.platform.LocalContext
13 | import androidx.compose.ui.tooling.preview.Preview
14 | import androidx.compose.ui.unit.dp
15 | import coil3.compose.AsyncImage
16 | import coil3.request.ImageRequest
17 | import coil3.request.crossfade
18 | import coil3.request.transformations
19 | import coil3.transform.RoundedCornersTransformation
20 |
21 |
22 | @Composable
23 | fun CoilImageLoading() {
24 | Box(
25 | modifier = Modifier
26 | .height(150.dp)
27 | .width(150.dp),
28 | contentAlignment = Alignment.Center
29 | ) {
30 | AsyncImage(
31 | model = ImageRequest.Builder(context = LocalContext.current)
32 | .data("https://avatars.githubusercontent.com/u/14994036?v=4")
33 | .crossfade(true)
34 | .transformations(
35 | RoundedCornersTransformation(50f)
36 | )
37 | .build(),
38 | contentDescription = "Profile Image",
39 | contentScale = ContentScale.Crop,
40 | modifier = Modifier.clip(CircleShape)
41 | )
42 | }
43 | }
44 |
45 | @Composable
46 | @Preview
47 | fun CoilImageLoadingPreview() {
48 | CoilImageLoading()
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/imageview/ImageViewPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.imageview
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.foundation.layout.size
8 | import androidx.compose.material.icons.Icons
9 | import androidx.compose.material.icons.filled.Add
10 | import androidx.compose.material3.Icon
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.ui.Alignment
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.graphics.Color
15 | import androidx.compose.ui.res.painterResource
16 | import androidx.compose.ui.tooling.preview.Preview
17 | import androidx.compose.ui.unit.dp
18 | import com.example.samplecomposeapp.R
19 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
20 |
21 |
22 | @Composable
23 | fun ImageViewPractice() {
24 | Box(modifier = Modifier
25 | .size(200.dp)
26 | .background(Color.Green)
27 | ) {
28 | Image(
29 | painter = painterResource(R.drawable.ic_launcher_foreground),
30 | contentDescription = null,
31 | modifier = Modifier
32 | .size(60.dp)
33 | .background(Color.Black)
34 | .align(Alignment.TopEnd)
35 | )
36 | Icon(
37 | imageVector = Icons.Default.Add,
38 | contentDescription = null,
39 | modifier = Modifier
40 | .align(Alignment.BottomStart)
41 | .background(Color.Red)
42 | )
43 | }
44 | }
45 |
46 | @Preview(showBackground = true)
47 | @Composable
48 | fun DefaultPreview(){
49 | SampleComposeAppTheme {
50 | ImageViewPractice()
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/navgraph/HomeNavGraph.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation.navgraph
2 |
3 | import android.util.Log
4 | import androidx.navigation.NavGraphBuilder
5 | import androidx.navigation.NavHostController
6 | import androidx.navigation.NavType
7 | import androidx.navigation.compose.composable
8 | import androidx.navigation.navArgument
9 | import androidx.navigation.navigation
10 | import com.example.samplecomposeapp.ui_practice.navigation.DETAIL_ARGUMENT_KEY
11 | import com.example.samplecomposeapp.ui_practice.navigation.DETAIL_ARGUMENT_KEY2
12 | import com.example.samplecomposeapp.ui_practice.navigation.HOME_ROUTE
13 | import com.example.samplecomposeapp.ui_practice.navigation.Screen
14 | import com.example.samplecomposeapp.ui_practice.navigation.screens.DetailScreen
15 | import com.example.samplecomposeapp.ui_practice.navigation.screens.HomeScreen
16 |
17 | fun NavGraphBuilder.homeNavGraph(navController: NavHostController){
18 | // Home Navigation Graph...//
19 | navigation(
20 | startDestination = Screen.Home.route,
21 | route = HOME_ROUTE
22 | ) {
23 | composable(
24 | route = Screen.Home.route
25 | ) {
26 | HomeScreen(navController)
27 | }
28 |
29 | composable(
30 | route = Screen.Detail.route,
31 | arguments = listOf(
32 | navArgument(DETAIL_ARGUMENT_KEY){
33 | type = NavType.IntType
34 | },
35 | navArgument(DETAIL_ARGUMENT_KEY2){
36 | type = NavType.StringType
37 | }
38 | )
39 | ) {
40 | Log.d("navgraph", "Args id :${it.arguments?.getInt(DETAIL_ARGUMENT_KEY).toString()} ")
41 | Log.d("navgraph", "Args Name:${it.arguments?.getString(DETAIL_ARGUMENT_KEY2)} ")
42 | DetailScreen(navController)
43 | }
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/lazyColumn/LazyColumn.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list.lazyColumn
2 |
3 | import androidx.compose.foundation.layout.Arrangement
4 | import androidx.compose.foundation.layout.PaddingValues
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.lazy.LazyColumn
7 | import androidx.compose.foundation.lazy.items
8 | import androidx.compose.material3.MaterialTheme
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.runtime.mutableStateListOf
11 | import androidx.compose.runtime.remember
12 | import androidx.compose.ui.Modifier
13 | import androidx.compose.ui.tooling.preview.Preview
14 | import androidx.compose.ui.unit.dp
15 | import com.example.samplecomposeapp.ui_practice.list.components.CustomItem
16 | import com.example.samplecomposeapp.ui_practice.list.model.Person
17 | import com.example.samplecomposeapp.ui_practice.list.repository.PersonRepository
18 |
19 | @Composable
20 | fun CustomLazyColumn(modifier: Modifier = Modifier, list: List) {
21 |
22 | LazyColumn(
23 | modifier = modifier.fillMaxSize(),
24 | verticalArrangement = Arrangement.spacedBy(8.dp),
25 | contentPadding = PaddingValues(8.dp)
26 | ) {
27 | items(list, key = { it.id }) { person ->
28 | CustomItem(person)
29 | }
30 |
31 | }
32 |
33 | }
34 |
35 |
36 | @Preview(showBackground = true)
37 | @Composable
38 | private fun CustomLazyColumnPreview() {
39 | MaterialTheme {
40 | val personList = remember {
41 | mutableStateListOf().apply {
42 | addAll(
43 | PersonRepository().getAllData()
44 | )
45 | }
46 | }
47 | CustomLazyColumn(
48 | list = personList
49 | )
50 | }
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/todo_list_check/TodoListViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement.todo_list_check
2 |
3 | import android.util.Log
4 | import androidx.lifecycle.ViewModel
5 | import com.example.samplecomposeapp.statemanagement.number_guess.NumberGuessState
6 | import kotlinx.coroutines.flow.MutableStateFlow
7 | import kotlinx.coroutines.flow.asStateFlow
8 | import kotlinx.coroutines.flow.update
9 | import java.util.UUID
10 |
11 | class TodoListViewModel: ViewModel() {
12 |
13 | private val _state = MutableStateFlow(
14 | listOf(
15 | TodoListState("1","Test", "Test Desc", false , false),
16 | TodoListState("2","Test1", "Test1 Desc", false , false),
17 | TodoListState("3","Test2", "Test2 Desc", false , false)
18 | )
19 | )
20 | val state = _state.asStateFlow()
21 |
22 | val listOfItem: List
23 | get() = _state.value
24 |
25 |
26 | fun onAction(action: TodoListActions){
27 | when(action){
28 |
29 | is TodoListActions.OnCheckedClick -> {
30 | val updatedList = listOfItem.map { item ->
31 | if (item.id == action.id) {
32 | item.copy(isChecked = !item.isChecked)
33 | } else item
34 | }
35 | _state.value = updatedList
36 | }
37 | is TodoListActions.OnDeleteClick -> {
38 | val updatedList = listOfItem.filter { it.id != action.id }
39 | _state.value = updatedList
40 | }
41 |
42 | is TodoListActions.OnAddItemClicked -> {
43 | val newItem = TodoListState(
44 | id = UUID.randomUUID().toString(),
45 | title = action.title,
46 | description = action.desc,
47 | isChecked = false,
48 | isDeleted = false
49 | )
50 | _state.value = listOfItem + newItem
51 | }
52 |
53 | }
54 | }
55 |
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/screens/LoginScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation.screens
2 |
3 | import androidx.compose.foundation.clickable
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.material3.MaterialTheme
8 | import androidx.compose.material3.Text
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Alignment
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.text.font.FontWeight
13 | import androidx.compose.ui.unit.dp
14 | import androidx.navigation.NavController
15 | import androidx.navigation.navOptions
16 | import com.example.samplecomposeapp.ui_practice.navigation.HOME_ROUTE
17 | import com.example.samplecomposeapp.ui_practice.navigation.Screen
18 |
19 |
20 | @Composable
21 | fun LoginScreen(navController: NavController) {
22 |
23 | Box(
24 | modifier = Modifier.fillMaxSize(),
25 | contentAlignment = Alignment.Center
26 | ){
27 | Text(
28 | modifier = Modifier.clickable {
29 | navController.navigate(route = Screen.SignUp.route)
30 | },
31 | text = "Login Screen",
32 | color = MaterialTheme.colorScheme.primary,
33 | fontSize = MaterialTheme.typography.headlineLarge.fontSize,
34 | fontWeight = FontWeight.Bold
35 | )
36 |
37 | Text(
38 | modifier = Modifier
39 | .padding(top = 150.dp)
40 | .clickable {
41 | navController.navigate(HOME_ROUTE){
42 | popUpTo(HOME_ROUTE)
43 | }
44 | },
45 | text = "Back",
46 | color = MaterialTheme.colorScheme.primary,
47 | fontSize = MaterialTheme.typography.headlineLarge.fontSize,
48 | fontWeight = FontWeight.Bold
49 | )
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/buttons/GradientButton.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.buttons
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.PaddingValues
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.material3.Button
8 | import androidx.compose.material3.ButtonDefaults
9 | import androidx.compose.material3.Text
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.ui.Alignment
12 | import androidx.compose.ui.Modifier
13 | import androidx.compose.ui.graphics.Brush
14 | import androidx.compose.ui.graphics.Color
15 | import androidx.compose.ui.tooling.preview.Preview
16 | import androidx.compose.ui.unit.dp
17 |
18 | @Composable
19 | fun GradientButton(
20 | text: String,
21 | textColor: Color,
22 | gradient: Brush,
23 | modifier: Modifier = Modifier,
24 | onClick: () -> Unit = {}
25 | ) {
26 | Button(
27 | modifier = modifier,
28 | colors = ButtonDefaults.buttonColors(
29 | contentColor = Color.White
30 | ),
31 | contentPadding = PaddingValues(),
32 | onClick = { onClick() }
33 | ) {
34 | Box(
35 | modifier = Modifier
36 | .background(gradient)
37 | .padding(horizontal = 16.dp, vertical = 8.dp),
38 | contentAlignment = Alignment.Center
39 | ) {
40 | Text(text = text, color = textColor)
41 | }
42 | }
43 | }
44 |
45 |
46 | @Composable
47 | @Preview
48 | fun GradientButtonPreview() {
49 | GradientButton(
50 | "Hit Me",
51 | Color.Blue, gradient = Brush.horizontalGradient(
52 | colors = listOf(
53 | Color(0x00000000),
54 | Color(0x00000000)
55 | )
56 | )
57 | )
58 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/snowflake.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textview/SubScriptAndSuperScript.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textview
2 |
3 | import androidx.compose.foundation.layout.Column
4 | import androidx.compose.foundation.layout.fillMaxSize
5 | import androidx.compose.material3.MaterialTheme
6 | import androidx.compose.material3.Text
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.ui.Modifier
9 | import androidx.compose.ui.text.SpanStyle
10 | import androidx.compose.ui.text.buildAnnotatedString
11 | import androidx.compose.ui.text.font.FontWeight
12 | import androidx.compose.ui.text.withStyle
13 | import androidx.compose.ui.tooling.preview.Preview
14 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
15 |
16 |
17 | @Composable
18 | fun SuperScriptText(
19 | normalText: String,
20 | superText: String
21 | ) {
22 | // Build Annotated String is used to Style Each Character of a string..//
23 | Text(buildAnnotatedString {
24 | withStyle(
25 | style =
26 | SpanStyle(fontSize = MaterialTheme.typography.bodyLarge.fontSize)
27 | ) {
28 | append(normalText)
29 | }
30 |
31 | withStyle(
32 | style = SpanStyle(
33 | fontSize = MaterialTheme.typography.bodySmall.fontSize,
34 | fontWeight = FontWeight.Normal,
35 | // to shift it to subscript change this baseline shift to subscript.
36 | baselineShift = androidx.compose.ui.text.style.BaselineShift.Superscript
37 | )
38 | ) {
39 | append(superText)
40 | }
41 | })
42 | }
43 |
44 |
45 | @Preview(showBackground = true)
46 | @Composable
47 | fun PreviewComposeable() {
48 | SampleComposeAppTheme {
49 | Column(modifier = Modifier.fillMaxSize()) {
50 | SuperScriptText("Sardar", "Khan")
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui.theme
2 |
3 | import android.os.Build
4 | import androidx.compose.foundation.isSystemInDarkTheme
5 | import androidx.compose.material3.MaterialTheme
6 | import androidx.compose.material3.darkColorScheme
7 | import androidx.compose.material3.dynamicDarkColorScheme
8 | import androidx.compose.material3.dynamicLightColorScheme
9 | import androidx.compose.material3.lightColorScheme
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.ui.platform.LocalContext
12 |
13 | private val DarkColorScheme = darkColorScheme(
14 | primary = Purple80,
15 | secondary = PurpleGrey80,
16 | tertiary = Pink80
17 | )
18 |
19 | private val LightColorScheme = lightColorScheme(
20 | primary = Purple40,
21 | secondary = PurpleGrey40,
22 | tertiary = Pink40
23 |
24 | /* Other default colors to override
25 | background = Color(0xFFFFFBFE),
26 | surface = Color(0xFFFFFBFE),
27 | onPrimary = Color.White,
28 | onSecondary = Color.White,
29 | onTertiary = Color.White,
30 | onBackground = Color(0xFF1C1B1F),
31 | onSurface = Color(0xFF1C1B1F),
32 | */
33 | )
34 |
35 | @Composable
36 | fun SampleComposeAppTheme(
37 | darkTheme: Boolean = isSystemInDarkTheme(),
38 | // Dynamic color is available on Android 12+
39 | dynamicColor: Boolean = true,
40 | content: @Composable () -> Unit
41 | ) {
42 | val colorScheme = when {
43 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
44 | val context = LocalContext.current
45 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
46 | }
47 |
48 | darkTheme -> DarkColorScheme
49 | else -> LightColorScheme
50 | }
51 |
52 | MaterialTheme(
53 | colorScheme = colorScheme,
54 | typography = Typography,
55 | content = content
56 | )
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/StateHoistingPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.Spacer
7 | import androidx.compose.foundation.layout.fillMaxSize
8 | import androidx.compose.foundation.layout.padding
9 | import androidx.compose.material3.Button
10 | import androidx.compose.material3.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.getValue
13 | import androidx.compose.runtime.mutableIntStateOf
14 | import androidx.compose.runtime.remember
15 | import androidx.compose.runtime.saveable.rememberSaveable
16 | import androidx.compose.runtime.setValue
17 | import androidx.compose.ui.Alignment
18 | import androidx.compose.ui.Modifier
19 | import androidx.compose.ui.graphics.Color
20 | import androidx.compose.ui.tooling.preview.Preview
21 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes
22 | import androidx.compose.ui.unit.dp
23 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
24 |
25 |
26 | @Composable
27 | fun StateHoistingPractice(modifier: Modifier = Modifier) {
28 |
29 | var counter by rememberSaveable {
30 | mutableIntStateOf(0)
31 | }
32 | Column (
33 | modifier = modifier.fillMaxSize(),
34 | horizontalAlignment = Alignment.CenterHorizontally,
35 | verticalArrangement = Arrangement.spacedBy(100.dp)
36 | ){
37 | Button(onClick = {
38 | counter = 0
39 | }) {
40 | Text(text = "Resent Counter.")
41 | }
42 | StatePractice(counter = counter,
43 | onCounterButtonClick = {
44 | counter++
45 | }, modifier = modifier)
46 |
47 | }
48 |
49 | }
50 |
51 |
52 |
53 | @PreviewScreenSizes
54 | @Preview(showBackground = true)
55 | @Composable
56 | private fun StateHoistingPrev() {
57 | SampleComposeAppTheme {
58 | StateHoistingPractice(modifier = Modifier
59 | .background(Color.Red)
60 |
61 | )
62 | }
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/navigation/screens/HomeScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.navigation.screens
2 |
3 | import androidx.compose.foundation.clickable
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.material3.MaterialTheme
8 | import androidx.compose.material3.Text
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Alignment
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.text.font.FontWeight
13 | import androidx.compose.ui.tooling.preview.Preview
14 | import androidx.compose.ui.unit.dp
15 | import androidx.navigation.NavController
16 | import androidx.navigation.compose.rememberNavController
17 | import com.example.samplecomposeapp.ui_practice.navigation.AUTHENTICATION_ROUTE
18 | import com.example.samplecomposeapp.ui_practice.navigation.Screen
19 |
20 | @Composable
21 | fun HomeScreen(navController: NavController) {
22 | Box(
23 | modifier = Modifier.fillMaxSize(),
24 | contentAlignment = Alignment.Center
25 | ){
26 | Text(
27 | modifier = Modifier.clickable {
28 | navController.navigate(route = Screen.Detail.passIdAndName(
29 | id = 1,
30 | name = "sardar"
31 | )
32 | )
33 | },
34 | text = "Home",
35 | color = MaterialTheme.colorScheme.primary,
36 | fontSize = MaterialTheme.typography.headlineLarge.fontSize,
37 | fontWeight = FontWeight.Bold
38 | )
39 |
40 | Text(
41 | modifier = Modifier
42 | .padding(top = 150.dp)
43 | .clickable {
44 | navController.navigate(AUTHENTICATION_ROUTE)
45 | },
46 | text = "Login/Sign Up",
47 | color = MaterialTheme.colorScheme.primary,
48 | fontSize = MaterialTheme.typography.headlineLarge.fontSize,
49 | fontWeight = FontWeight.Bold
50 | )
51 | }
52 | }
53 |
54 |
55 | @Preview(showBackground = true)
56 | @Composable
57 | private fun HomeScreenPreview() {
58 | HomeScreen(
59 | navController = rememberNavController()
60 | )
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/components/CustomItem.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list.components
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Row
6 | import androidx.compose.foundation.layout.fillMaxWidth
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.material3.Text
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Alignment
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.graphics.Color
13 | import androidx.compose.ui.text.font.FontWeight
14 | import androidx.compose.ui.tooling.preview.Preview
15 | import androidx.compose.ui.unit.dp
16 | import com.example.samplecomposeapp.ui.theme.Typography
17 | import com.example.samplecomposeapp.ui_practice.list.model.Person
18 |
19 | @Composable
20 | fun CustomItem(person: Person) {
21 | Row(
22 | modifier = Modifier
23 | .background(Color.LightGray)
24 | .fillMaxWidth()
25 | .padding(24.dp),
26 | verticalAlignment = Alignment.CenterVertically,
27 | horizontalArrangement = Arrangement.spacedBy(12.dp)
28 | ) {
29 | Text(
30 | text = "${person.age}",
31 | color = Color.Black,
32 | fontSize = Typography.bodySmall.fontSize,
33 | fontWeight = FontWeight.Bold
34 | )
35 | Text(
36 | text = person.firstName,
37 | color = Color.Black,
38 | fontSize = Typography.bodyLarge.fontSize,
39 | fontWeight = FontWeight.Normal
40 | )
41 | Text(
42 | text = person.lastName,
43 | color = Color.Black,
44 | fontSize = Typography.bodyMedium.fontSize,
45 | fontWeight = FontWeight.Normal
46 | )
47 | }
48 | }
49 |
50 |
51 | @Composable
52 | @Preview
53 | fun CustomItemPreview() {
54 | CustomItem(
55 | person = Person(
56 | id = 0,
57 | firstName = "John",
58 | lastName = "Doe",
59 | age = 20
60 | )
61 | )
62 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/cutlery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/number_guess/NumberGuessViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement.number_guess
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateOf
5 | import androidx.compose.runtime.setValue
6 | import androidx.lifecycle.ViewModel
7 | import kotlinx.coroutines.flow.MutableStateFlow
8 | import kotlinx.coroutines.flow.asStateFlow
9 | import kotlinx.coroutines.flow.update
10 | import kotlin.random.Random
11 |
12 | class NumberGuessViewModel: ViewModel() {
13 |
14 | // to save the state..//
15 | // var screenState by mutableStateOf(NumberGuessState())
16 | // private set
17 |
18 | // alternative approach to save state..Recommended approach...//
19 | private val _state = MutableStateFlow(NumberGuessState())
20 | val state = _state.asStateFlow()
21 |
22 | private var number = Random.nextInt(0,101)
23 | private var attempts = 0
24 |
25 |
26 | fun onAction(action: NumberGuessAction) {
27 | when(action){
28 | NumberGuessAction.OnGuessClick ->{
29 | val guess = _state.value.numberText.toIntOrNull()
30 | if(guess!=null) {
31 | attempts++
32 | }
33 |
34 | _state.update {
35 | it.copy(
36 | guessText = when{
37 | guess == null -> "Please Enter a number."
38 | number > guess -> "Nope, my number is larger."
39 | number < guess -> "Nope, my number is smaller."
40 | else -> "That was it! You needed $attempts attempts."
41 | },
42 | isGuessCorrect = guess == number,
43 | numberText = ""
44 | )
45 | }
46 | }
47 | is NumberGuessAction.OnNumberTextChange -> {
48 | _state.update { it.copy(
49 | numberText = action.newNumberText
50 | )
51 | }
52 | }
53 |
54 | NumberGuessAction.OnStartNewGameButton ->{
55 | _state.update {
56 | number = Random.nextInt(1,101)
57 | it.copy(
58 | numberText = "",
59 | guessText = null,
60 | isGuessCorrect = false
61 | )
62 | }
63 | }
64 |
65 | }
66 | }
67 |
68 |
69 |
70 |
71 |
72 |
73 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bed.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/modifiers/ClickableModifierPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.modifiers
2 |
3 | import androidx.compose.foundation.LocalIndication
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.clickable
6 | import androidx.compose.foundation.interaction.MutableInteractionSource
7 | import androidx.compose.foundation.interaction.collectIsHoveredAsState
8 | import androidx.compose.foundation.interaction.collectIsPressedAsState
9 | import androidx.compose.foundation.layout.Box
10 | import androidx.compose.foundation.layout.size
11 | import androidx.compose.material3.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.runtime.getValue
14 | import androidx.compose.runtime.remember
15 | import androidx.compose.ui.Alignment
16 | import androidx.compose.ui.Modifier
17 | import androidx.compose.ui.graphics.Color
18 | import androidx.compose.ui.tooling.preview.Preview
19 | import androidx.compose.ui.unit.dp
20 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
21 |
22 | @Composable
23 | fun ClickableModifierPractice(modifier: Modifier = Modifier) {
24 | val interactionSource =
25 | remember { MutableInteractionSource() }
26 |
27 | val isPressed by interactionSource.collectIsPressedAsState()
28 | val isHovered by interactionSource.collectIsHoveredAsState()
29 | // Box (
30 | // modifier = Modifier
31 | // .size(100.dp)
32 | // .background(Color.White)
33 | // .clickable(
34 | // enabled = false,
35 | // onClickLabel = "Test" // for accessibility..//
36 | // ){
37 | // println("Hello World..")
38 | // },
39 | // contentAlignment = Alignment.Center
40 | // ){
41 | // Text(text = "Hello World")
42 | // }
43 |
44 | Box (
45 | modifier = Modifier
46 | .size(100.dp)
47 | .background(
48 | if (isPressed) Color.Blue else Color.White
49 | )
50 | .clickable(
51 | interactionSource,
52 | LocalIndication.current
53 | ){
54 | println("Hello World..")
55 | },
56 | contentAlignment = Alignment.Center
57 | ){
58 | Text(text = "Hello World")
59 | }
60 | }
61 |
62 | @Preview
63 | @Composable
64 | private fun ClickableModifierPracticePrev() {
65 | SampleComposeAppTheme {
66 | ClickableModifierPractice()
67 | }
68 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/modifiers/SpacingModifierPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.modifiers
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.ExperimentalLayoutApi
7 | import androidx.compose.foundation.layout.Spacer
8 | import androidx.compose.foundation.layout.fillMaxSize
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.foundation.layout.height
11 | import androidx.compose.foundation.layout.imeNestedScroll
12 | import androidx.compose.foundation.layout.navigationBarsPadding
13 | import androidx.compose.foundation.layout.padding
14 | import androidx.compose.foundation.layout.safeContentPadding
15 | import androidx.compose.foundation.layout.safeDrawingPadding
16 | import androidx.compose.foundation.layout.safeGesturesPadding
17 | import androidx.compose.foundation.layout.size
18 | import androidx.compose.foundation.layout.statusBarsPadding
19 | import androidx.compose.foundation.lazy.LazyColumn
20 | import androidx.compose.material3.Text
21 | import androidx.compose.material3.TextField
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.Modifier
24 | import androidx.compose.ui.graphics.Color
25 | import androidx.compose.ui.tooling.preview.Preview
26 | import androidx.compose.ui.unit.dp
27 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
28 |
29 | @OptIn(ExperimentalLayoutApi::class)
30 | @Composable
31 | fun SpacingModifierPractice(modifier: Modifier = Modifier) {
32 |
33 | Column (
34 | modifier = modifier
35 | .safeDrawingPadding()
36 | .fillMaxSize()
37 | ){
38 |
39 | LazyColumn(
40 | modifier = Modifier.fillMaxWidth()
41 | .weight(1f)
42 | .imeNestedScroll()
43 | ) {
44 | items(100){
45 | Text(
46 | text = "Testing Text $it"
47 | )
48 | Spacer(
49 | modifier = Modifier
50 | .fillMaxWidth()
51 | .padding(16.dp)
52 | )
53 | }
54 | }
55 | TextField(
56 | value = "",
57 | onValueChange = {}
58 | )
59 |
60 | }
61 | }
62 |
63 |
64 | @Preview
65 | @Composable
66 | private fun SpacingModifierPracticePrev() {
67 | SampleComposeAppTheme {
68 | SpacingModifierPractice()
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/lazyColumn/LazyColumnPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list.lazyColumn
2 |
3 | import androidx.compose.foundation.ExperimentalFoundationApi
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.Arrangement
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.PaddingValues
8 | import androidx.compose.foundation.layout.fillMaxSize
9 | import androidx.compose.foundation.layout.height
10 | import androidx.compose.foundation.layout.padding
11 | import androidx.compose.foundation.lazy.LazyColumn
12 | import androidx.compose.foundation.lazy.items
13 | import androidx.compose.material3.Text
14 | import androidx.compose.runtime.Composable
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.graphics.Color
17 | import androidx.compose.ui.tooling.preview.Preview
18 | import androidx.compose.ui.unit.dp
19 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
20 |
21 |
22 | @OptIn(ExperimentalFoundationApi::class)
23 | @Composable
24 | fun LazyColumnPractice(modifier: Modifier = Modifier) {
25 | LazyColumn (
26 | modifier = Modifier.fillMaxSize()
27 | .height(200.dp)
28 | .padding(16.dp)
29 | .background(Color.Red),
30 | contentPadding = PaddingValues(16.dp),
31 | verticalArrangement = Arrangement.SpaceEvenly
32 | ){
33 | items(100){ i->
34 | Text("item $i")
35 | }
36 |
37 | stickyHeader {
38 | Text(text = "Sticky Header..",
39 | modifier = Modifier.fillMaxSize()
40 | .background(Color.Green)
41 | )
42 | }
43 | items(100){ i->
44 | Text("item $i")
45 | }
46 |
47 | stickyHeader {
48 | Text(text = "Sticky Header..",
49 | modifier = Modifier.fillMaxSize()
50 | .background(Color.Green)
51 | )
52 | }
53 | items(100){ i->
54 | Text("item $i")
55 | }
56 | // last Item in List..//
57 | item {
58 | Text(
59 | text = "Footer Reached the End...",
60 | modifier = Modifier.fillMaxSize()
61 | .background(Color.Red)
62 | )
63 | }
64 |
65 |
66 |
67 | }
68 | }
69 |
70 | @Preview(showBackground = true)
71 | @Composable
72 | private fun LazyColumnPracticePreview() {
73 | SampleComposeAppTheme {
74 | LazyColumnPractice()
75 | }
76 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/television.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
27 |
30 |
33 |
36 |
39 |
42 |
45 |
48 |
51 |
52 |
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.application)
3 | alias(libs.plugins.kotlin.android)
4 | alias(libs.plugins.kotlin.compose)
5 | }
6 |
7 | android {
8 | namespace = "com.example.samplecomposeapp"
9 | compileSdk = libs.versions.compileSdkVersion.get().toInt()
10 |
11 | defaultConfig {
12 | applicationId = "com.example.samplecomposeapp"
13 | minSdk = libs.versions.minSdkVersion.get().toInt()
14 | targetSdk = libs.versions.targetSdkVersion.get().toInt()
15 | versionCode = libs.versions.versionCode.get().toInt()
16 | versionName = libs.versions.versionName.get()
17 |
18 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
19 | }
20 |
21 | buildTypes {
22 | release {
23 | isMinifyEnabled = false
24 | proguardFiles(
25 | getDefaultProguardFile("proguard-android-optimize.txt"),
26 | "proguard-rules.pro"
27 | )
28 | }
29 | }
30 | compileOptions {
31 | sourceCompatibility = JavaVersion.VERSION_11
32 | targetCompatibility = JavaVersion.VERSION_11
33 | }
34 | kotlinOptions {
35 | jvmTarget = "11"
36 | }
37 | buildFeatures {
38 | compose = true
39 | }
40 | }
41 |
42 | dependencies {
43 |
44 | implementation(libs.androidx.lifecycle.runtime.compose)
45 | implementation(libs.androidx.lifecycle.viewmodel.compose)
46 | implementation(libs.androidx.core.ktx)
47 | implementation(libs.androidx.lifecycle.runtime.ktx)
48 | implementation(libs.androidx.activity.compose)
49 | implementation(platform(libs.androidx.compose.bom))
50 | implementation(libs.androidx.adaptive.android)
51 | implementation(libs.androidx.ui)
52 | implementation(libs.androidx.ui.graphics)
53 | implementation(libs.androidx.ui.tooling.preview)
54 | implementation(libs.androidx.material3)
55 | implementation(libs.coil.compose.v304)
56 | implementation(libs.coil.network.okhttp.v304)
57 | implementation(libs.androidx.navigation.runtime.ktx)
58 | implementation(libs.androidx.navigation.compose)
59 | testImplementation(libs.junit)
60 | androidTestImplementation(libs.androidx.junit)
61 | androidTestImplementation(libs.androidx.espresso.core)
62 | androidTestImplementation(platform(libs.androidx.compose.bom))
63 | androidTestImplementation(libs.androidx.ui.test.junit4)
64 | debugImplementation(libs.androidx.ui.tooling)
65 | debugImplementation(libs.androidx.ui.test.manifest)
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/lazyGrid/LazyGridDemo.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list.lazyGrid
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.PaddingValues
7 | import androidx.compose.foundation.layout.height
8 | import androidx.compose.foundation.layout.size
9 | import androidx.compose.foundation.layout.width
10 | import androidx.compose.foundation.lazy.grid.GridCells
11 | import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
12 | import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
13 | import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
14 | import androidx.compose.foundation.shape.RoundedCornerShape
15 | import androidx.compose.runtime.Composable
16 | import androidx.compose.ui.Modifier
17 | import androidx.compose.ui.draw.clip
18 | import androidx.compose.ui.graphics.Color
19 | import androidx.compose.ui.tooling.preview.Preview
20 | import androidx.compose.ui.unit.dp
21 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
22 | import kotlin.random.Random
23 | import kotlin.random.nextInt
24 |
25 |
26 | @Composable
27 | fun LazyGridDemo() {
28 | // LazyVerticalGrid(
29 | // columns = GridCells.Adaptive(50.dp),
30 | // verticalArrangement = Arrangement.spacedBy(16.dp),
31 | // horizontalArrangement = Arrangement.spacedBy(16.dp),
32 | // contentPadding = PaddingValues(16.dp)
33 | // ) {
34 | // items(100){
35 | // Box(
36 | // modifier = Modifier
37 | // .width(
38 | // width = Random.nextInt(1..200).dp
39 | // )
40 | // .height(100.dp)
41 | // .background(Color(Random.nextInt()))
42 | //
43 | // )
44 | // }
45 | // }
46 |
47 |
48 | // Staggred Grid for Different Height for Cells..//
49 | LazyVerticalStaggeredGrid(
50 | columns = StaggeredGridCells.Fixed(5),
51 | horizontalArrangement = Arrangement.spacedBy(16.dp),
52 | contentPadding = PaddingValues(16.dp)
53 | ) {
54 | items(100){
55 | Box(
56 | modifier = Modifier
57 | .height(
58 | height = Random.nextInt(1..200).dp
59 | )
60 | .clip(RoundedCornerShape(8.dp))
61 | .background(Color(Random.nextInt()))
62 |
63 | )
64 | }
65 | }
66 |
67 | }
68 |
69 |
70 | @Preview
71 | @Composable
72 | private fun LazyGridPrev() {
73 | SampleComposeAppTheme {
74 | LazyGridDemo()
75 | }
76 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/layouts/BoxPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.layouts
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.foundation.layout.size
8 | import androidx.compose.material.icons.Icons
9 | import androidx.compose.material.icons.filled.Star
10 | import androidx.compose.material3.Icon
11 | import androidx.compose.material3.IconButton
12 | import androidx.compose.material3.Text
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.ui.Alignment
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.graphics.Brush
17 | import androidx.compose.ui.graphics.Color
18 | import androidx.compose.ui.res.painterResource
19 | import androidx.compose.ui.tooling.preview.Preview
20 | import androidx.compose.ui.unit.dp
21 | import com.example.samplecomposeapp.R
22 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
23 |
24 |
25 | @Composable
26 | fun BoxPractice(modifier: Modifier = Modifier) {
27 | Box(
28 | modifier = Modifier.fillMaxSize()
29 | .background(Color.Black),
30 | contentAlignment = Alignment.BottomCenter
31 | ) {
32 |
33 | Image(
34 | painter = painterResource(R.drawable.ic_launcher_foreground),
35 | contentDescription = null,
36 | Modifier.background(color = Color.White)
37 | )
38 |
39 | Box(
40 | modifier = Modifier
41 | .matchParentSize()
42 | .background(
43 | brush = Brush.verticalGradient(
44 | colors = listOf(
45 | Color.Transparent,
46 | Color.LightGray
47 | )
48 | )
49 | )
50 | ){
51 |
52 | }
53 |
54 | IconButton(onClick = {},
55 | modifier = Modifier.align(Alignment.BottomEnd)) {
56 | Icon(
57 | imageVector = Icons.Default.Star,
58 | contentDescription = null,
59 | tint = Color.Blue
60 | )
61 | }
62 |
63 | Text(
64 | text = "Hello World..",
65 | color = Color.Blue,
66 | modifier = Modifier.align(Alignment.TopStart)
67 | )
68 | Text(
69 | text = "Hi How are you..",
70 | color = Color.Red,
71 | modifier = Modifier.align(Alignment.BottomStart)
72 | )
73 |
74 | }
75 | }
76 |
77 | @Preview(showBackground = true,
78 | backgroundColor = 0xff)
79 | @Composable
80 | private fun RowColumnPreview() {
81 | SampleComposeAppTheme {
82 | BoxPractice()
83 | }
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textField/CharacterCountTextField.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textField
2 |
3 | import androidx.compose.material3.OutlinedTextField
4 |
5 |
6 | import android.util.Log
7 | import androidx.compose.foundation.layout.Arrangement
8 | import androidx.compose.foundation.layout.Column
9 | import androidx.compose.foundation.layout.fillMaxSize
10 | import androidx.compose.foundation.text.KeyboardActions
11 | import androidx.compose.foundation.text.KeyboardOptions
12 | import androidx.compose.material.icons.Icons
13 | import androidx.compose.material.icons.filled.Done
14 | import androidx.compose.material.icons.filled.Email
15 | import androidx.compose.material3.Icon
16 | import androidx.compose.material3.IconButton
17 | import androidx.compose.material3.Text
18 | import androidx.compose.material3.TextField
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.runtime.getValue
21 | import androidx.compose.runtime.mutableStateOf
22 | import androidx.compose.runtime.remember
23 | import androidx.compose.runtime.setValue
24 | import androidx.compose.ui.Alignment
25 | import androidx.compose.ui.Modifier
26 | import androidx.compose.ui.text.input.ImeAction
27 | import androidx.compose.ui.text.input.KeyboardType
28 | import androidx.compose.ui.tooling.preview.Preview
29 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
30 |
31 |
32 | @Composable
33 | fun CharacterCountComposable() {
34 |
35 | Column(
36 | modifier = Modifier.fillMaxSize(),
37 | horizontalAlignment = Alignment.CenterHorizontally,
38 | verticalArrangement = Arrangement.Center
39 | ) {
40 | var text by remember { mutableStateOf("") }
41 |
42 | val maxCharacter = 10
43 |
44 | OutlinedTextField(
45 | value = text,
46 | onValueChange = { newText ->
47 | if (newText.length <= maxCharacter){
48 | text = newText
49 | }
50 | },
51 | readOnly = false,
52 | label = {
53 | Text(text = "Name")
54 | },
55 | placeholder = { Text(text="Enter Your Name") },
56 | maxLines = 1,
57 | leadingIcon = {
58 | IconButton(onClick = {}) {
59 | Icon(imageVector = Icons.Default.Email, contentDescription = "Email Icon")
60 | }
61 | },
62 | trailingIcon = {
63 | IconButton(onClick = {}) {
64 | Icon(imageVector = Icons.Default.Done, contentDescription = "Done Icon")
65 | }
66 | },
67 |
68 | )
69 |
70 |
71 | }
72 | }
73 |
74 |
75 | @Composable
76 | @Preview
77 | fun CharacterCountComposablePreview() {
78 | SampleComposeAppTheme {
79 | CharacterCountComposable()
80 | }
81 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/AndroidConnectivityObserver.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp
2 |
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.ConnectivityManager.NetworkCallback
6 | import android.net.Network
7 | import android.net.NetworkCapabilities
8 | import android.util.Log
9 | import kotlinx.coroutines.channels.awaitClose
10 | import kotlinx.coroutines.flow.Flow
11 | import kotlinx.coroutines.flow.callbackFlow
12 |
13 | class AndroidConnectivityObserver(context: Context) : ConnectivityObserver {
14 |
15 | private val connectivityManager =
16 | context.getSystemService(Context.CONNECTIVITY_SERVICE)!! as ConnectivityManager
17 | override val isConnected: Flow
18 | get() = callbackFlow {
19 | val callback = object : NetworkCallback() {
20 | override fun onAvailable(network: Network) {
21 | super.onAvailable(network)
22 | Log.d(AndroidConnectivityObserver::class.simpleName, ": onAvailable")
23 | trySend(true)
24 | }
25 |
26 | override fun onLosing(network: Network, maxMsToLive: Int) {
27 | super.onLosing(network, maxMsToLive)
28 |
29 | Log.d(AndroidConnectivityObserver::class.simpleName, ": onLosing")
30 | }
31 |
32 | override fun onLost(network: Network) {
33 | super.onLost(network)
34 | Log.d(AndroidConnectivityObserver::class.simpleName, ": onLost")
35 | trySend(false)
36 | }
37 |
38 | override fun onUnavailable() {
39 | super.onUnavailable()
40 | Log.d(AndroidConnectivityObserver::class.simpleName, ": onUnavailable")
41 | trySend(false)
42 | }
43 |
44 | override fun onCapabilitiesChanged(
45 | network: Network,
46 | networkCapabilities: NetworkCapabilities
47 | ) {
48 | super.onCapabilitiesChanged(network, networkCapabilities)
49 | Log.d(AndroidConnectivityObserver::class.simpleName, ": onCapability Change")
50 | val connected =
51 | networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
52 | trySend(connected)
53 | }
54 | }
55 | connectivityManager.registerDefaultNetworkCallback(callback)
56 | awaitClose {
57 | connectivityManager.unregisterNetworkCallback(callback)
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/layouts/FlowLayout.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.layouts
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.ExperimentalLayoutApi
6 | import androidx.compose.foundation.layout.FlowRow
7 | import androidx.compose.foundation.layout.FlowRowOverflow
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.Spacer
10 | import androidx.compose.foundation.layout.fillMaxSize
11 | import androidx.compose.foundation.layout.width
12 | import androidx.compose.material.icons.Icons
13 | import androidx.compose.material.icons.filled.KeyboardArrowDown
14 | import androidx.compose.material.icons.filled.KeyboardArrowUp
15 | import androidx.compose.material3.AssistChip
16 | import androidx.compose.material3.Icon
17 | import androidx.compose.material3.IconButton
18 | import androidx.compose.material3.Text
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.Alignment
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.graphics.Color
23 | import androidx.compose.ui.tooling.preview.Preview
24 | import androidx.compose.ui.unit.dp
25 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
26 |
27 | @OptIn(ExperimentalLayoutApi::class)
28 | @Composable
29 | fun FlowLayout(modifier: Modifier = Modifier) {
30 |
31 | FlowRow(
32 | modifier = modifier
33 | .fillMaxSize()
34 | .background(Color.Red),
35 | horizontalArrangement = Arrangement.spacedBy(
36 | space = 20.dp
37 | ),
38 | verticalArrangement = Arrangement.Top,
39 | maxLines = 4,
40 | overflow = FlowRowOverflow.expandOrCollapseIndicator(
41 | expandIndicator = {
42 | IconButton(onClick = {}) {
43 | Icon(imageVector = Icons.Default.KeyboardArrowDown,
44 | contentDescription = "Expand")
45 | }
46 | },
47 | collapseIndicator = {
48 | IconButton(onClick = {}) {
49 | Icon(imageVector = Icons.Default.KeyboardArrowUp,
50 | contentDescription = "Expand")
51 | }
52 | }
53 | )
54 | ) {
55 | for (i in 1..30) {
56 |
57 | AssistChip(
58 | onClick = {},
59 | label = {
60 | Text(
61 | text = "Item $i",
62 | Modifier.background(Color.Green)
63 | )
64 | },
65 | modifier = Modifier.background(color = Color.Blue)
66 | )
67 | }
68 |
69 | }
70 | }
71 |
72 |
73 | @Preview(showBackground = true,
74 | backgroundColor = 0xff)
75 | @Composable
76 | private fun FlowLayoutPreview() {
77 | SampleComposeAppTheme {
78 | FlowLayout()
79 | }
80 | }
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textField/PasswordInputField.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textField
2 |
3 | import androidx.compose.foundation.layout.Arrangement
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.text.KeyboardOptions
7 | import androidx.compose.material3.Icon
8 | import androidx.compose.material3.IconButton
9 | import androidx.compose.material3.OutlinedTextField
10 | import androidx.compose.material3.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.getValue
13 | import androidx.compose.runtime.mutableStateOf
14 | import androidx.compose.runtime.remember
15 | import androidx.compose.runtime.saveable.rememberSaveable
16 | import androidx.compose.runtime.setValue
17 | import androidx.compose.ui.Alignment
18 | import androidx.compose.ui.Modifier
19 | import androidx.compose.ui.res.painterResource
20 | import androidx.compose.ui.text.input.KeyboardType
21 | import androidx.compose.ui.text.input.PasswordVisualTransformation
22 | import androidx.compose.ui.text.input.VisualTransformation
23 | import androidx.compose.ui.tooling.preview.Preview
24 | import com.example.samplecomposeapp.R
25 |
26 |
27 | @Composable
28 | fun PasswordInputField() {
29 | Column(
30 | modifier = Modifier.fillMaxSize(),
31 | horizontalAlignment = Alignment.CenterHorizontally,
32 | verticalArrangement = Arrangement.Center
33 | ) {
34 | var password by rememberSaveable { mutableStateOf("") }
35 | var passwordVisibility by remember { mutableStateOf(false) }
36 | var icon = if (passwordVisibility)
37 | painterResource(id = R.drawable.ic_launcher_foreground)
38 | else painterResource(id = R.drawable.ic_launcher_background)
39 | OutlinedTextField(
40 | value = password,
41 | onValueChange = {
42 | password = it
43 | },
44 | placeholder = {
45 | Text("Enter password...")
46 | },
47 | trailingIcon = {
48 | IconButton(onClick = {
49 | passwordVisibility = !passwordVisibility
50 | }) {
51 | Icon(
52 | painter = icon,
53 | contentDescription = "Image"
54 | )
55 | }
56 | },
57 | keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
58 | visualTransformation = if (passwordVisibility) VisualTransformation.None
59 | else PasswordVisualTransformation()
60 | )
61 |
62 |
63 | }
64 | }
65 |
66 |
67 | @Composable
68 | @Preview
69 | fun CoilImageLoadingPreview() {
70 | PasswordInputField()
71 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textField/TextFieldCompose.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textField
2 |
3 | import android.util.Log
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.foundation.text.KeyboardActions
8 | import androidx.compose.foundation.text.KeyboardOptions
9 | import androidx.compose.material.icons.Icons
10 | import androidx.compose.material.icons.filled.Done
11 | import androidx.compose.material.icons.filled.Email
12 | import androidx.compose.material3.Icon
13 | import androidx.compose.material3.IconButton
14 | import androidx.compose.material3.Text
15 | import androidx.compose.material3.TextField
16 | import androidx.compose.runtime.Composable
17 | import androidx.compose.runtime.getValue
18 | import androidx.compose.runtime.mutableStateOf
19 | import androidx.compose.runtime.remember
20 | import androidx.compose.runtime.setValue
21 | import androidx.compose.ui.Alignment
22 | import androidx.compose.ui.Modifier
23 | import androidx.compose.ui.text.input.ImeAction
24 | import androidx.compose.ui.text.input.KeyboardType
25 | import androidx.compose.ui.tooling.preview.Preview
26 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
27 |
28 |
29 | @Composable
30 | fun TextFieldCompose() {
31 |
32 | Column(
33 | modifier = Modifier.fillMaxSize(),
34 | horizontalAlignment = Alignment.CenterHorizontally,
35 | verticalArrangement = Arrangement.Center
36 | ) {
37 | var text by remember { mutableStateOf("Type Here...") }
38 | TextField(value = text,
39 | onValueChange = { newText ->
40 | text = newText
41 | },
42 | readOnly = false,
43 | label = {
44 | Text(text = "Enter Your Name")
45 | },
46 | singleLine = false,
47 | maxLines = 2,
48 | leadingIcon = {
49 | IconButton(onClick = {}) {
50 | Icon(imageVector = Icons.Default.Email, contentDescription = "Email Icon")
51 | }
52 | },
53 | trailingIcon = {
54 | IconButton(onClick = {}) {
55 | Icon(imageVector = Icons.Default.Done, contentDescription = "Done Icon")
56 | }
57 | },
58 | keyboardOptions = KeyboardOptions(
59 | keyboardType = KeyboardType.Number,
60 | imeAction = ImeAction.Search
61 | ),
62 | keyboardActions = KeyboardActions(
63 | onSearch = {
64 | Log.d("TAG", "TextFieldCompose: $text")
65 | },
66 | onDone = {
67 | Log.d("TAG", "TextFieldCompose: $text")
68 | }
69 | )
70 |
71 | )
72 |
73 |
74 | }
75 | }
76 |
77 |
78 | @Composable
79 | @Preview
80 | fun TextFieldPreview() {
81 | SampleComposeAppTheme {
82 | TextFieldCompose()
83 | }
84 | }
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | agp = "8.7.1"
3 | coilComposeVersion = "3.0.4"
4 | coilNetworkOkhttpVersion = "3.0.4"
5 | kotlin = "2.0.0"
6 | coreKtx = "1.13.1"
7 | junit = "4.13.2"
8 | junitVersion = "1.2.1"
9 | espressoCore = "3.6.1"
10 | lifecycleRuntimeKtx = "2.6.1"
11 | activityCompose = "1.8.0"
12 | composeBom = "2024.04.01"
13 | minSdkVersion = "24"
14 | compileSdkVersion = "34"
15 | targetSdkVersion = "34"
16 | versionName = "1.0"
17 | versionCode = "1"
18 | lifecycle = "2.8.7"
19 | navigationRuntimeKtx = "2.8.5"
20 | navigationCompose = "2.8.5"
21 | adaptiveAndroid = "1.0.0"
22 |
23 | [libraries]
24 | androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
25 | coil-compose-v304 = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilComposeVersion" }
26 | coil-network-okhttp-v304 = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coilNetworkOkhttpVersion" }
27 | junit = { group = "junit", name = "junit", version.ref = "junit" }
28 | androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
29 | androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
30 | androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
31 | androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
32 | androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
33 | androidx-ui = { group = "androidx.compose.ui", name = "ui" }
34 | androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
35 | androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
36 | androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
37 | androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
38 | androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
39 | androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
40 |
41 | androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycle" }
42 | androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" }
43 | androidx-navigation-runtime-ktx = { group = "androidx.navigation", name = "navigation-runtime-ktx", version.ref = "navigationRuntimeKtx" }
44 | androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
45 | androidx-adaptive-android = { group = "androidx.compose.material3.adaptive", name = "adaptive-android", version.ref = "adaptiveAndroid" }
46 |
47 | [plugins]
48 | android-application = { id = "com.android.application", version.ref = "agp" }
49 | kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
50 | kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pawprint.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/StatePractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement
2 |
3 | import androidx.compose.foundation.gestures.snapping.SnapPosition
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Row
8 | import androidx.compose.foundation.layout.Spacer
9 | import androidx.compose.foundation.layout.fillMaxSize
10 | import androidx.compose.foundation.layout.padding
11 | import androidx.compose.material3.Button
12 | import androidx.compose.material3.Text
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.runtime.getValue
15 | import androidx.compose.runtime.mutableIntStateOf
16 | import androidx.compose.runtime.mutableStateOf
17 | import androidx.compose.runtime.remember
18 | import androidx.compose.runtime.saveable.rememberSaveable
19 | import androidx.compose.runtime.setValue
20 | import androidx.compose.ui.Alignment
21 | import androidx.compose.ui.Modifier
22 | import androidx.compose.ui.tooling.preview.Preview
23 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes
24 | import androidx.compose.ui.unit.dp
25 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
26 | import com.example.samplecomposeapp.ui_practice.PracticeScreens.HotelBookingScreen
27 | import org.intellij.lang.annotations.JdkConstants.HorizontalAlignment
28 |
29 |
30 | // this cannot be a state because its a constant and it cannot be changed over time....//
31 | private const val BASE_URL = "https://...."
32 |
33 | // never update state in composable function..//
34 | // state should be update from...normal lambdas..or non composable lambdas..//
35 |
36 | // compose state needs to update in a full..
37 | /// avoid use mutable dataStructure in jetpack compose ..//
38 | // mutableListof() and
39 |
40 | @Composable
41 | fun StatePractice(counter:Int,
42 | onCounterButtonClick: ()-> Unit,
43 | modifier: Modifier = Modifier) {
44 | // this can be used or served as a state..//
45 | // remember is used to cached the value across recomposition..//
46 | // and remember it can only be used in the context of composable functions..//
47 | //var count by remember { mutableIntStateOf(0) }
48 |
49 | // remember saveable is used to cache the value when screen rotates..//
50 | var items by rememberSaveable {
51 | mutableStateOf(listOf(
52 | "Item"
53 | )
54 | )
55 | }
56 |
57 | Column (
58 | modifier = modifier.fillMaxSize(),
59 | horizontalAlignment = Alignment.CenterHorizontally,
60 | verticalArrangement = Arrangement.Center
61 | ){
62 |
63 | Button(onClick = {
64 | onCounterButtonClick.invoke()
65 | }) {
66 | Text("Count is $counter")
67 | }
68 | Button(onClick = {
69 | items += "item"
70 | }) {
71 | Text("Add Item..")
72 | }
73 | Text(text = items.toString(),
74 | modifier = modifier.align(Alignment.CenterHorizontally)
75 |
76 | )
77 | }
78 | }
79 |
80 |
81 | @PreviewScreenSizes
82 | @Preview(showBackground = true)
83 | @Composable
84 | private fun StatePracticePreview() {
85 | SampleComposeAppTheme {
86 | StatePractice(counter = 0, {})
87 | }
88 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/statemanagement/number_guess/StateManagementGame.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.statemanagement.number_guess
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.foundation.text.KeyboardOptions
8 | import androidx.compose.material3.Button
9 | import androidx.compose.material3.Text
10 | import androidx.compose.material3.TextField
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.getValue
13 | import androidx.compose.runtime.saveable.rememberSaveable
14 | import androidx.compose.ui.Alignment
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.graphics.Color
17 | import androidx.compose.ui.text.input.KeyboardType
18 | import androidx.compose.ui.tooling.preview.Preview
19 | import androidx.compose.ui.tooling.preview.PreviewLightDark
20 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes
21 | import androidx.compose.ui.unit.dp
22 | import androidx.lifecycle.compose.collectAsStateWithLifecycle
23 | import androidx.lifecycle.viewmodel.compose.viewModel
24 | import com.example.samplecomposeapp.statemanagement.StateHoistingPractice
25 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
26 |
27 | @Composable
28 | fun NumberGuessScreenRoot(modifier: Modifier = Modifier) {
29 | val viewModel = viewModel()
30 | val state by viewModel.state.collectAsStateWithLifecycle()
31 | StateManagementGame(modifier = modifier,
32 | state = state,
33 | onAction = viewModel::onAction // pass action to viewModel to handle..//
34 | )
35 | }
36 |
37 | @Composable
38 | fun StateManagementGame(state: NumberGuessState,
39 | modifier: Modifier = Modifier,
40 | onAction: (NumberGuessAction)-> Unit) {
41 |
42 | Column (
43 | modifier = modifier.fillMaxSize(),
44 | horizontalAlignment = Alignment.CenterHorizontally,
45 | verticalArrangement = Arrangement.spacedBy(16.dp,Alignment.CenterVertically)
46 | ){
47 | TextField(
48 | value = state.numberText,
49 | onValueChange = { newText->
50 | onAction(NumberGuessAction.OnNumberTextChange(newText))
51 | },
52 | label = {
53 | Text(text = "Enter Number")
54 | },
55 | keyboardOptions = KeyboardOptions(
56 | keyboardType = KeyboardType.Number
57 | )
58 | )
59 | Button(
60 | onClick = {
61 | onAction(NumberGuessAction.OnGuessClick)
62 | }
63 | ) {
64 | Text(text = "Make Guess...")
65 | }
66 |
67 | if(state.guessText != null){
68 | Text(
69 | text = state.guessText
70 | )
71 | }
72 |
73 | if(state.isGuessCorrect){
74 | Button(onClick = {
75 | onAction(NumberGuessAction.OnStartNewGameButton)
76 | }) {
77 | Text(text = "Start new game...")
78 | }
79 | }
80 |
81 |
82 | }
83 |
84 | }
85 |
86 | @PreviewScreenSizes
87 | @PreviewLightDark
88 | @Composable
89 | @Preview(showBackground = true)
90 | private fun StateManagementGamePrev() {
91 | SampleComposeAppTheme {
92 | StateManagementGame(
93 | state = NumberGuessState(numberText = "",
94 | guessText = "",
95 | isGuessCorrect = false
96 | ),
97 | onAction = {}
98 | )
99 | }
100 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PracticeComposeComponents
2 |
3 | [](https://kotlinlang.org/)
4 | [](https://developer.android.com/jetpack/compose)
5 | [](https://github.com/SardarKhan299/PracticeComposeComponents/pulls)
6 |
7 | This repository is dedicated to practicing and showcasing various **Jetpack Compose Components**. Jetpack Compose is Android's modern UI toolkit that simplifies and accelerates UI development.
8 |
9 | Here, you'll find examples of reusable UI components, layouts, and animations created using Jetpack Compose. Whether you're a beginner looking to learn Compose or an experienced developer wanting to contribute, this project is for you!
10 |
11 | ---
12 |
13 | ## ✨ **Features**
14 | - 🚀 **Hands-on Jetpack Compose components:** Button, TextField, LazyColumn, and more.
15 | - 🎨 **UI snippets:** Examples that are ready to use in your projects.
16 | - 🧑🏫 **Learning-oriented code:** Organized and beginner-friendly examples.
17 | - 💡 **Collaborative environment:** Open for community contributions and feedback.
18 |
19 | ---
20 |
21 | ## 🛠️ **Getting Started**
22 |
23 | 1. **Clone the Repository:**
24 | ```bash
25 | git clone https://github.com/SardarKhan299/PracticeComposeComponents.git
26 | ```
27 |
28 | 2. **Open in Android Studio:**
29 | - Ensure you have Android Studio **Arctic Fox or later** installed.
30 | - Open the project from the cloned directory.
31 |
32 | 3. **Build and Run:**
33 | - Connect an emulator or a physical Android device.
34 | - Click the "Run" button to see the components in action.
35 |
36 | ---
37 |
38 | ## 🌱 **How to Contribute**
39 |
40 | Contributions are welcome! Follow these steps to make your contributions:
41 |
42 | 1. **Fork the Repository:**
43 | Click the **Fork** button on the top right of this repository.
44 |
45 | 2. **Create a New Branch:**
46 | ```bash
47 | git checkout -b feature-name
48 | ```
49 |
50 | 3. **Make Changes:**
51 | - Add a new Jetpack Compose component or improve existing ones.
52 | - Ensure your code follows Kotlin and Compose best practices.
53 |
54 | 4. **Commit and Push:**
55 | ```bash
56 | git add .
57 | git commit -m "Added new Compose component: XYZ"
58 | git push origin feature-name
59 | ```
60 |
61 | 5. **Create a Pull Request:**
62 | - Go to your forked repository on GitHub.
63 | - Click the **Compare & Pull Request** button and explain your changes.
64 |
65 | ---
66 |
67 | ## 🤝 **Join the Community**
68 |
69 | Looking to improve your Compose skills? Collaborate with others by:
70 | - Sharing feedback on existing components.
71 | - Suggesting ideas for new components.
72 | - Reporting bugs or issues in the repository.
73 |
74 | Check out the **[Issues section](https://github.com/SardarKhan299/PracticeComposeComponents/issues)** to see how you can help!
75 |
76 | ---
77 |
78 | ## 📜 **License**
79 |
80 | This project is licensed under the **MIT License**—feel free to use, modify, and distribute!
81 |
82 | ---
83 |
84 | ## 💬 **Connect with Us**
85 |
86 | Got questions or suggestions? Feel free to open an issue or start a discussion in the [Discussions section](https://github.com/SardarKhan299/PracticeComposeComponents/discussions).
87 | Or Send me an Email @ sardar.khan299@gmail.com
88 | Happy Coding! 🚀
89 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/windowSizeClass/WindowSizeClassDemo.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.windowSizeClass
2 |
3 | import android.view.Window
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Row
8 | import androidx.compose.foundation.layout.fillMaxHeight
9 | import androidx.compose.foundation.layout.fillMaxSize
10 | import androidx.compose.foundation.layout.padding
11 | import androidx.compose.foundation.layout.width
12 | import androidx.compose.foundation.lazy.LazyColumn
13 | import androidx.compose.material3.Scaffold
14 | import androidx.compose.material3.Text
15 | import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
16 | import androidx.compose.runtime.Composable
17 | import androidx.compose.ui.Modifier
18 | import androidx.compose.ui.graphics.Color
19 | import androidx.compose.ui.tooling.preview.Devices
20 | import androidx.compose.ui.tooling.preview.Preview
21 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes
22 | import androidx.compose.ui.unit.dp
23 | import androidx.navigation.compose.rememberNavController
24 | import androidx.window.core.layout.WindowWidthSizeClass
25 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
26 |
27 | @Composable
28 | fun WindowSizeClassDemo() {
29 | val windowClass = currentWindowAdaptiveInfo().windowSizeClass
30 | when(windowClass.windowWidthSizeClass){
31 |
32 | }
33 | Scaffold { innerPadding->
34 | Box(
35 | modifier = Modifier
36 | .fillMaxSize()
37 | .padding(innerPadding)
38 | ){
39 | when(windowClass.windowWidthSizeClass){
40 | WindowWidthSizeClass.COMPACT ->{
41 | Text(text = "Compat")
42 | MyLazyList()
43 | }
44 | WindowWidthSizeClass.MEDIUM ->{
45 | Text(text = "Medium")
46 | MyLazyList()
47 | }
48 | WindowWidthSizeClass.EXPANDED ->{
49 | Text(text = "Expanded")
50 | Row (modifier = Modifier.fillMaxSize()) {
51 | Column(
52 | modifier = Modifier.fillMaxHeight()
53 | .weight(2f)
54 | .background(Color.Red)
55 | ) {
56 | Text(text = "Menu Option 1")
57 | Text(text = "Menu Option 2")
58 | Text(text = "Menu Option 3")
59 | }
60 | MyLazyList(modifier = Modifier
61 | .fillMaxHeight()
62 | .weight(6f))
63 |
64 | Column(
65 | modifier = Modifier.fillMaxHeight()
66 | .weight(2f)
67 | .background(Color.Blue)
68 | ) {
69 | Text(text = "Menu Option 1")
70 | Text(text = "Menu Option 2")
71 | Text(text = "Menu Option 3")
72 | }
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
79 | }
80 |
81 |
82 | @Composable
83 | fun MyLazyList(modifier: Modifier = Modifier) {
84 | LazyColumn(modifier = modifier.fillMaxSize()){
85 | items(100){
86 | Text(text = "Item $it",
87 | modifier = Modifier.padding(16.dp))
88 | }
89 | }
90 | }
91 |
92 | @PreviewScreenSizes
93 | @Preview(showBackground = true,
94 | widthDp = 1000,
95 | device = Devices.NEXUS_7)
96 | @Composable
97 | private fun WindowSizeClassPreview() {
98 | SampleComposeAppTheme {
99 | WindowSizeClassDemo()
100 | }
101 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/layouts/RowColumnDemo.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.layouts
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Row
8 | import androidx.compose.foundation.layout.fillMaxSize
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.foundation.layout.size
11 | import androidx.compose.foundation.layout.width
12 | import androidx.compose.material3.HorizontalDivider
13 | import androidx.compose.material3.Text
14 | import androidx.compose.material3.VerticalDivider
15 | import androidx.compose.runtime.Composable
16 | import androidx.compose.ui.Alignment
17 | import androidx.compose.ui.Modifier
18 | import androidx.compose.ui.graphics.Color
19 | import androidx.compose.ui.layout.LastBaseline
20 | import androidx.compose.ui.tooling.preview.Preview
21 | import androidx.compose.ui.unit.dp
22 | import androidx.compose.ui.unit.sp
23 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
24 |
25 | @Composable
26 | fun RowColumnDemo(modifier: Modifier = Modifier) {
27 |
28 | // Column (modifier = Modifier.fillMaxSize()){
29 | // Text("Item 1", color = Color.White)
30 | // HorizontalDivider(color = Color.Blue)
31 | // Text("Item 2", color = Color.White)
32 | // }
33 |
34 | // Row practice...//
35 | // Row (
36 | // modifier = Modifier.fillMaxSize(),
37 | // verticalAlignment = Alignment.CenterVertically,
38 | // horizontalArrangement = Arrangement.spacedBy(
39 | // space = 20.dp, alignment = Alignment.CenterHorizontally)
40 | // ){
41 | // Box(
42 | // modifier = Modifier.size(100.dp)
43 | // .background(Color.Red)
44 | // )
45 | // Box(
46 | // modifier = Modifier.size(100.dp)
47 | // .background(Color.Blue)
48 | // .align(Alignment.Bottom)
49 | // )
50 | // Box(
51 | // modifier = Modifier.size(100.dp)
52 | // .background(Color.Green)
53 | // )
54 | // }
55 |
56 | // Row (
57 | // modifier = Modifier.fillMaxSize(),
58 | // verticalAlignment = Alignment.CenterVertically,
59 | // horizontalArrangement = Arrangement.spacedBy(
60 | // space = 20.dp, alignment = Alignment.CenterHorizontally)
61 | // ){
62 | // Text(
63 | // text = "Hello World",
64 | // fontSize = 40.sp,
65 | // color = Color.Blue,
66 | // modifier = Modifier
67 | // .width(120.dp)
68 | // .alignBy(LastBaseline)
69 | // )
70 | // Text(text = "Hello World 1..",
71 | // fontSize = 20.sp,
72 | // color = Color.Red,
73 | // modifier = Modifier.alignByBaseline()
74 | //
75 | // )
76 | // }
77 |
78 | Column (
79 | modifier = Modifier.fillMaxSize(),
80 | horizontalAlignment = Alignment.CenterHorizontally,
81 | verticalArrangement = Arrangement.SpaceEvenly
82 | ){
83 | Box(
84 | modifier = Modifier.size(100.dp)
85 | .background(Color.Red)
86 | .weight(1f)
87 | )
88 | Box(
89 | modifier = Modifier.size(100.dp)
90 | .background(Color.Blue)
91 | .weight(0.5f)
92 | )
93 | Box(
94 | modifier = Modifier.size(100.dp)
95 | .background(Color.Green)
96 | .weight(1f)
97 | )
98 | }
99 | }
100 |
101 | @Preview(showBackground = true,
102 | backgroundColor = 0xff)
103 | @Composable
104 | private fun RowColumnPreview() {
105 | SampleComposeAppTheme {
106 | RowColumnDemo()
107 | }
108 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/serving_dish.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | xmlns:android
15 |
16 | ^$
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | xmlns:.*
26 |
27 | ^$
28 |
29 |
30 | BY_NAME
31 |
32 |
33 |
34 |
35 |
36 |
37 | .*:id
38 |
39 | http://schemas.android.com/apk/res/android
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | .*:name
49 |
50 | http://schemas.android.com/apk/res/android
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | name
60 |
61 | ^$
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | style
71 |
72 | ^$
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | .*
82 |
83 | ^$
84 |
85 |
86 | BY_NAME
87 |
88 |
89 |
90 |
91 |
92 |
93 | .*
94 |
95 | http://schemas.android.com/apk/res/android
96 |
97 |
98 | ANDROID_ATTRIBUTE_ORDER
99 |
100 |
101 |
102 |
103 |
104 |
105 | .*
106 |
107 | .*
108 |
109 |
110 | BY_NAME
111 |
112 |
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/android.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
27 |
30 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textField/GoogleSignUpButton.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textField
2 |
3 | import androidx.compose.animation.animateContentSize
4 | import androidx.compose.animation.core.LinearOutSlowInEasing
5 | import androidx.compose.animation.core.tween
6 | import androidx.compose.foundation.BorderStroke
7 | import androidx.compose.foundation.layout.Arrangement
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.Spacer
10 | import androidx.compose.foundation.layout.height
11 | import androidx.compose.foundation.layout.padding
12 | import androidx.compose.foundation.layout.width
13 | import androidx.compose.material3.CircularProgressIndicator
14 | import androidx.compose.material3.Icon
15 | import androidx.compose.material3.MaterialTheme
16 | import androidx.compose.material3.Shapes
17 | import androidx.compose.material3.Surface
18 | import androidx.compose.material3.Text
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.runtime.getValue
21 | import androidx.compose.runtime.mutableStateOf
22 | import androidx.compose.runtime.remember
23 | import androidx.compose.runtime.setValue
24 | import androidx.compose.ui.Alignment
25 | import androidx.compose.ui.Modifier
26 | import androidx.compose.ui.graphics.Color
27 | import androidx.compose.ui.graphics.Shape
28 | import androidx.compose.ui.graphics.painter.Painter
29 | import androidx.compose.ui.res.painterResource
30 | import androidx.compose.ui.tooling.preview.Preview
31 | import androidx.compose.ui.unit.dp
32 | import com.example.samplecomposeapp.R
33 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
34 |
35 | @Composable
36 | fun GoogleButtonCompose(
37 | text: String = "Sign Up With Goole",
38 | loadingText: String = "Creating Account...",
39 | icon: Painter = painterResource(R.drawable.ic_launcher_foreground),
40 | shape: Shape = Shapes().medium,
41 | borderColour: Color = Color.LightGray,
42 | backgroundColor: Color = MaterialTheme.colorScheme.surface,
43 | progressIndicatorColor: Color = MaterialTheme.colorScheme.primary,
44 | onclicked: () -> Unit
45 | ) {
46 | var clicked by remember { mutableStateOf(false) }
47 |
48 | Surface(
49 | onClick = { clicked = !clicked },
50 | shape = shape,
51 | border = BorderStroke(width = 1.dp, color = borderColour),
52 | color = backgroundColor,
53 | )
54 | {
55 | Row(
56 | horizontalArrangement = Arrangement.Center,
57 | verticalAlignment = Alignment.CenterVertically,
58 | modifier = Modifier
59 | .padding(start = 12.dp, end = 16.dp, top = 12.dp, bottom = 12.dp)
60 | .height(50.dp)
61 | .animateContentSize(
62 | animationSpec = tween(
63 | durationMillis = 300,
64 | easing = LinearOutSlowInEasing
65 | )
66 | )
67 | )
68 | {
69 | Icon(
70 | painter = icon, contentDescription = "Google Logo",
71 | tint = Color.Unspecified
72 | )
73 | Spacer(modifier = Modifier.width(8.dp))
74 | Text(text = if (clicked) loadingText else text)
75 | if (clicked) {
76 | Spacer(modifier = Modifier.width(8.dp))
77 | CircularProgressIndicator(
78 | modifier = Modifier
79 | .height(16.dp)
80 | .width(16.dp),
81 | strokeWidth = 2.dp,
82 | color = progressIndicatorColor
83 | )
84 | onclicked()
85 | }
86 | }
87 |
88 |
89 | }
90 | }
91 |
92 |
93 | @Preview(showBackground = true)
94 | @Composable
95 | fun GoogleButtonPreview() {
96 | SampleComposeAppTheme {
97 | GoogleButtonCompose(onclicked = {
98 | println("Clicked")
99 | })
100 | }
101 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/breakfast.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textview/TextComposable.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textview
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.foundation.layout.size
9 | import androidx.compose.foundation.text.selection.DisableSelection
10 | import androidx.compose.foundation.text.selection.SelectionContainer
11 | import androidx.compose.material3.MaterialTheme
12 | import androidx.compose.material3.Text
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.ui.Alignment
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.draw.clip
17 | import androidx.compose.ui.graphics.Color
18 | import androidx.compose.ui.res.stringResource
19 | import androidx.compose.ui.text.SpanStyle
20 | import androidx.compose.ui.text.buildAnnotatedString
21 | import androidx.compose.ui.text.font.FontStyle
22 | import androidx.compose.ui.text.font.FontWeight
23 | import androidx.compose.ui.text.style.TextAlign
24 | import androidx.compose.ui.text.withStyle
25 | import androidx.compose.ui.tooling.preview.Preview
26 | import androidx.compose.ui.unit.dp
27 | import androidx.compose.ui.unit.sp
28 | import com.example.samplecomposeapp.R
29 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
30 |
31 |
32 | @Composable
33 | fun CustomizeText() {
34 | Text(
35 | text = stringResource(R.string.app_name), modifier = Modifier
36 | .background(Color.Blue)
37 | .padding(16.dp),
38 | color = Color.White,
39 | fontSize = MaterialTheme.typography.bodyLarge.fontSize,
40 | fontStyle = FontStyle.Italic,
41 | fontWeight = FontWeight.Bold,
42 | textAlign = TextAlign.Center
43 | )
44 | }
45 |
46 | @Composable
47 | fun CustomizeText2() {
48 | Text(
49 | buildAnnotatedString {
50 | withStyle(style = SpanStyle(color = Color.Red)) {
51 | append("S")
52 | }
53 | withStyle(style = SpanStyle(color = Color.Blue)) {
54 | append("A")
55 | }
56 | append("S")
57 | append("A")
58 | append("R")
59 | }
60 | )
61 | }
62 |
63 | @Composable
64 | fun CustomizeText3() {
65 | SelectionContainer {
66 | Column {
67 | Text(text = "Hello from Android")
68 | DisableSelection {
69 | Text(text = "Hello from Android 1")
70 | }
71 | Text(text = "Hello from Android 2")
72 | }
73 | }
74 | }
75 |
76 | @Composable
77 | fun GreetingText(name: String){
78 | Text(
79 | text = "Hello. $name!",
80 | color = Color.Blue,
81 | fontSize = 30.sp,
82 | modifier = Modifier
83 | .background(Color.Red)
84 | .padding(16.dp)
85 | .background(Color.Green)
86 | .padding(8.dp)
87 | .background(Color.Black)
88 | )
89 | }
90 |
91 | @Composable
92 | fun TextOnEachOther(name: String){
93 | Box(
94 | modifier = Modifier
95 | .size(400.dp)
96 | ) {
97 | Text(
98 | text = "Hello. $name!",
99 | color = Color.Blue,
100 | fontSize = 30.sp,
101 | modifier = Modifier.align(Alignment.BottomEnd)
102 | )
103 | Text(
104 | text = "Some Other text",
105 | color = Color.Blue,
106 | fontSize = 30.sp,
107 | )
108 | }
109 | }
110 |
111 | @Preview(showBackground = true)
112 | @Composable
113 | fun DefaultPreview() {
114 | SampleComposeAppTheme {
115 | Column(modifier = Modifier.fillMaxSize()) {
116 | CustomizeText()
117 | CustomizeText2()
118 | CustomizeText3()
119 | GreetingText("Sardar Khan")
120 | TextOnEachOther("Sardar Khan")
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/list/ListPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.list
2 |
3 | import android.util.Log
4 | import android.view.Display.Mode
5 | import androidx.compose.foundation.layout.Arrangement
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Row
8 | import androidx.compose.foundation.layout.Spacer
9 | import androidx.compose.foundation.layout.fillMaxSize
10 | import androidx.compose.foundation.layout.fillMaxWidth
11 | import androidx.compose.foundation.layout.padding
12 | import androidx.compose.foundation.layout.size
13 | import androidx.compose.foundation.layout.width
14 | import androidx.compose.foundation.lazy.LazyColumn
15 | import androidx.compose.foundation.lazy.items
16 | import androidx.compose.material.icons.Icons
17 | import androidx.compose.material.icons.filled.Add
18 | import androidx.compose.material3.Button
19 | import androidx.compose.material3.Divider
20 | import androidx.compose.material3.HorizontalDivider
21 | import androidx.compose.material3.Icon
22 | import androidx.compose.material3.OutlinedTextField
23 | import androidx.compose.material3.Text
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.runtime.getValue
26 | import androidx.compose.runtime.mutableIntStateOf
27 | import androidx.compose.runtime.mutableStateOf
28 | import androidx.compose.runtime.remember
29 | import androidx.compose.runtime.setValue
30 | import androidx.compose.ui.Alignment
31 | import androidx.compose.ui.Modifier
32 | import androidx.compose.ui.tooling.preview.Preview
33 | import androidx.compose.ui.unit.dp
34 | import androidx.compose.ui.unit.sp
35 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
36 |
37 |
38 | @Composable
39 | fun ListPractice(){
40 | LazyColumn(modifier = Modifier.fillMaxSize()) {
41 | items(100){
42 | Icon(
43 | imageVector = Icons.Default.Add,
44 | contentDescription = null,
45 | modifier = Modifier.size(30.dp)
46 | )
47 |
48 | }
49 |
50 | }
51 |
52 | }
53 |
54 | @Composable
55 | fun ListPractice2(){
56 | var name by remember {
57 | mutableStateOf("")
58 | }
59 |
60 | var names by remember {
61 | mutableStateOf(listOf(""))
62 | }
63 |
64 | Column (
65 | modifier = Modifier
66 | .fillMaxSize()
67 | .padding(16.dp)
68 | ) {
69 |
70 | Row(
71 | modifier = Modifier.fillMaxWidth()
72 | ) {
73 | OutlinedTextField(
74 | value = name,
75 | onValueChange = { text->
76 | name = text
77 | },
78 | modifier = Modifier.weight(1f)
79 | )
80 |
81 | Spacer(modifier = Modifier.width(16.dp))
82 |
83 | Button(onClick = {
84 | if(name.isNotEmpty())
85 | names = names + name
86 | name = ""
87 | }) {
88 | Text(text = "Add")
89 | }
90 |
91 | }
92 |
93 | LazyColumn {
94 | items(names){ currentName->
95 | Text(text = currentName,
96 | modifier = Modifier.fillMaxWidth()
97 | .padding(16.dp))
98 | HorizontalDivider()
99 | }
100 |
101 | }
102 |
103 | }
104 |
105 |
106 |
107 |
108 | }
109 |
110 | @Composable
111 | fun StatePractice(){
112 | Log.d("ListPractice", ": State Practice ");
113 | Column(
114 | modifier = Modifier.fillMaxSize(),
115 | verticalArrangement = Arrangement.Center,
116 | horizontalAlignment = Alignment.CenterHorizontally
117 | ) {
118 | var count by remember { mutableIntStateOf(0) }
119 | Log.d("ListPractice", ": Text Recomposing ");
120 | Text(text = count.toString(),
121 | fontSize = 30.sp)
122 | Button(onClick = {
123 | Log.d("ListPractice", ": Button Click.. ");
124 | count++
125 | }) {
126 | Log.d("ListPractice", ":Button Text recomposition ");
127 | Text(text = "Click Me $count")
128 | }
129 |
130 | }
131 | }
132 |
133 |
134 |
135 | @Preview(showBackground = true)
136 | @Composable
137 | fun ListPracticePreview(){
138 | SampleComposeAppTheme {
139 | //ListPractice()
140 | //StatePractice()
141 | ListPractice2()
142 | }
143 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/layouts/Scaffold.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.layouts
2 |
3 | import android.util.Log
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.material.icons.Icons
9 | import androidx.compose.material.icons.automirrored.filled.ArrowBack
10 | import androidx.compose.material.icons.filled.Add
11 | import androidx.compose.material.icons.filled.Search
12 | import androidx.compose.material.icons.filled.Star
13 | import androidx.compose.material3.BottomAppBar
14 | import androidx.compose.material3.ExperimentalMaterial3Api
15 | import androidx.compose.material3.FloatingActionButton
16 | import androidx.compose.material3.Icon
17 | import androidx.compose.material3.IconButton
18 | import androidx.compose.material3.NavigationBarItem
19 | import androidx.compose.material3.Scaffold
20 | import androidx.compose.material3.Snackbar
21 | import androidx.compose.material3.SnackbarHost
22 | import androidx.compose.material3.SnackbarHostState
23 | import androidx.compose.material3.Text
24 | import androidx.compose.material3.TopAppBar
25 | import androidx.compose.material3.TopAppBarState
26 | import androidx.compose.runtime.Composable
27 | import androidx.compose.runtime.remember
28 | import androidx.compose.runtime.rememberCoroutineScope
29 | import androidx.compose.ui.Modifier
30 | import androidx.compose.ui.graphics.Color
31 | import androidx.compose.ui.tooling.preview.Preview
32 | import androidx.compose.ui.unit.sp
33 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
34 | import kotlinx.coroutines.launch
35 |
36 | @OptIn(ExperimentalMaterial3Api::class)
37 | @Composable
38 | fun ScaffoldPractice() {
39 |
40 | val snackBarState = remember {
41 | SnackbarHostState()
42 | }
43 |
44 | val scope = rememberCoroutineScope()
45 | Scaffold(
46 | topBar = {
47 | TopAppBar(
48 | title = {
49 | Text(text = "Hello World Top Bar...")
50 | },
51 | navigationIcon = {
52 | IconButton(onClick = {}) {
53 | Icon (imageVector = Icons.AutoMirrored.Default.ArrowBack,
54 | contentDescription = "Go Back...."
55 | )
56 | }
57 | },
58 | actions = {
59 | IconButton(onClick = {}) {
60 | }
61 | }
62 | )
63 | },
64 | bottomBar = {
65 | BottomAppBar {
66 | NavigationBarItem(
67 | selected = true,
68 | onClick = {},
69 | icon = {
70 | Icon(imageVector = Icons.Default.Star,
71 | contentDescription = null)
72 | },
73 | label = {
74 | Text("Favourites")
75 | }
76 | )
77 | NavigationBarItem(
78 | selected = false,
79 | onClick = {},
80 | icon = {
81 | Icon(imageVector = Icons.Default.Search,
82 | contentDescription = null)
83 | },
84 | label = {
85 | Text("Search")
86 | }
87 | )
88 | }
89 | },
90 | floatingActionButton = {
91 | FloatingActionButton(onClick = {
92 | Log.d("Scaffold", "Clicked..: ");
93 | scope.launch {
94 | snackBarState.showSnackbar("FAB Clicked...")
95 | }
96 |
97 | }) {
98 | Icon(imageVector = Icons.Default.Add,
99 | contentDescription = null)
100 | }
101 | },
102 | snackbarHost = {
103 | SnackbarHost(
104 | hostState = snackBarState,
105 | ) { }
106 | }
107 | ) {
108 | contentPadding ->
109 | Box(
110 | modifier = Modifier
111 | .fillMaxSize()
112 | .padding(contentPadding)
113 | .background(Color.Red)
114 | ){
115 | Text(text = "Hello Text Box...",
116 | fontSize = 16.sp
117 | )
118 | }
119 | }
120 | }
121 |
122 | @Preview(showBackground = true,
123 | backgroundColor = 0xff)
124 | @Composable
125 | private fun ScaffoldPreview() {
126 | SampleComposeAppTheme {
127 | ScaffoldPractice()
128 | }
129 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/modifiers/ShapeModifierPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.modifiers
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.foundation.layout.size
7 | import androidx.compose.foundation.shape.CircleShape
8 | import androidx.compose.foundation.shape.RoundedCornerShape
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.draw.clip
12 | import androidx.compose.ui.geometry.Size
13 | import androidx.compose.ui.graphics.Color
14 | import androidx.compose.ui.graphics.Outline
15 | import androidx.compose.ui.graphics.Path
16 | import androidx.compose.ui.graphics.Shape
17 | import androidx.compose.ui.graphics.copy
18 | import androidx.compose.ui.res.painterResource
19 | import androidx.compose.ui.tooling.preview.Preview
20 | import androidx.compose.ui.unit.Density
21 | import androidx.compose.ui.unit.LayoutDirection
22 | import androidx.compose.ui.unit.dp
23 | import com.example.samplecomposeapp.R
24 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
25 | import java.lang.StrictMath.tan
26 | import kotlin.math.PI
27 |
28 | fun Int.toRadian() = this * PI / 180
29 |
30 | @Composable
31 | fun ShapeModifierPractice(modifier: Modifier = Modifier) {
32 |
33 | // First image...//
34 | // Image(
35 | // painter = painterResource(R.drawable.android),
36 | // contentDescription = null,
37 | // modifier = Modifier
38 | // .size(200.dp)
39 | // .clip(CircleShape)
40 | // .background(Color.Red)
41 | // .padding(8.dp)
42 | // )
43 |
44 |
45 |
46 | // Second Image..//
47 | // Image(
48 | // painter = painterResource(R.drawable.android),
49 | // contentDescription = null,
50 | // modifier = Modifier
51 | // .size(200.dp)
52 | // .clip(RoundedCornerShape(
53 | // topStartPercent = 50,
54 | // topEndPercent = 20,
55 | // bottomEndPercent = 20,
56 | // bottomStartPercent = 20
57 | // ))
58 | // .background(Color.Red)
59 | // .padding(8.dp)
60 | // )
61 |
62 | // Third Image..//
63 | Image(
64 | painter = painterResource(R.drawable.android),
65 | contentDescription = null,
66 | modifier = Modifier
67 | .size(200.dp)
68 | .clip(StarShape)
69 | .background(Color.Red)
70 | .padding(8.dp)
71 | )
72 |
73 | }
74 |
75 | data object TriangleShape: Shape {
76 |
77 | override fun createOutline(
78 | size: Size,
79 | layoutDirection: LayoutDirection,
80 | density: Density
81 | ): Outline {
82 | return Outline.Generic(
83 | path = Path().apply {
84 | moveTo(
85 | x = size.width / 2f,
86 | y= 0f
87 | )
88 | lineTo(
89 | x = 0f,
90 | y = size.height
91 | )
92 | lineTo(
93 | x = size.width,
94 | y = size.height
95 | )
96 | close()
97 | }
98 | )
99 | }
100 |
101 | }
102 |
103 | object StarShape : Shape {
104 | override fun createOutline(
105 | size: Size,
106 | layoutDirection: LayoutDirection,
107 | density: Density
108 | ): Outline {
109 |
110 | val width = size.width
111 | val height = size.height
112 |
113 | val pointOne = Pair(width / 2, 0f)
114 | val pointTwo = Pair((width / 2) - (height * tan(18.toRadian())), height)
115 | val pointThree = Pair(width, height - ((width + 2 * height * tan(18.toRadian())) / (2 * tan(54.toRadian()))))
116 | val pointFour = Pair(0f, height - ((width + 2 * height * tan(18.toRadian())) / (2 * tan(54.toRadian()))))
117 | val pointFive = Pair((width / 2 + height * tan(18.toRadian())), height)
118 |
119 | return Outline.Generic(
120 | path = Path().apply {
121 | moveTo(
122 | x = pointOne.first,
123 | y = pointOne.second
124 | )
125 | lineTo(
126 | x = pointTwo.first.toFloat(),
127 | y = pointTwo.second
128 | )
129 | lineTo(
130 | x = pointThree.first,
131 | y = pointThree.second.toFloat()
132 | )
133 | lineTo(
134 | x = pointFour.first.toFloat(),
135 | y = pointFour.second.toFloat()
136 | )
137 | lineTo(
138 | x = pointFive.first.toFloat(),
139 | y = pointFive.second
140 | )
141 | close()
142 | }
143 | )
144 | }
145 | }
146 |
147 | @Preview
148 | @Composable
149 | private fun ShapeModifierPracticePrev() {
150 | SampleComposeAppTheme {
151 | ShapeModifierPractice()
152 | }
153 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/textview/ExpandableCard.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.textview
2 |
3 | import androidx.compose.animation.animateContentSize
4 | import androidx.compose.animation.core.LinearOutSlowInEasing
5 | import androidx.compose.animation.core.animateFloatAsState
6 | import androidx.compose.animation.core.tween
7 | import androidx.compose.foundation.layout.Column
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.foundation.layout.padding
11 | import androidx.compose.foundation.shape.CornerBasedShape
12 | import androidx.compose.material.icons.Icons
13 | import androidx.compose.material.icons.filled.ArrowDropDown
14 | import androidx.compose.material3.Card
15 | import androidx.compose.material3.Icon
16 | import androidx.compose.material3.IconButton
17 | import androidx.compose.material3.MaterialTheme
18 | import androidx.compose.material3.Shapes
19 | import androidx.compose.material3.Text
20 | import androidx.compose.runtime.Composable
21 | import androidx.compose.runtime.getValue
22 | import androidx.compose.runtime.mutableStateOf
23 | import androidx.compose.runtime.remember
24 | import androidx.compose.runtime.setValue
25 | import androidx.compose.ui.Alignment
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.draw.alpha
28 | import androidx.compose.ui.draw.rotate
29 | import androidx.compose.ui.text.font.FontWeight
30 | import androidx.compose.ui.text.style.TextOverflow
31 | import androidx.compose.ui.tooling.preview.Preview
32 | import androidx.compose.ui.unit.Dp
33 | import androidx.compose.ui.unit.TextUnit
34 | import androidx.compose.ui.unit.dp
35 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
36 |
37 |
38 | @Composable
39 | fun ExpandableCard(
40 | title: String,
41 | titleFontSize: TextUnit = MaterialTheme.typography.bodyLarge.fontSize,
42 | titleFontWeight: FontWeight = FontWeight.Bold,
43 | descriptionText: String,
44 | descriptionFontSize: TextUnit = MaterialTheme.typography.bodySmall.fontSize,
45 | descriptionFontWeight: FontWeight = FontWeight.Normal,
46 | descriptionMaxLines: Int = 4,
47 | cardShape: CornerBasedShape = Shapes().medium,
48 | padding: Dp = 12.dp,
49 | durations: Int = 300,
50 |
51 | ) {
52 | var expanded by remember { mutableStateOf(false) }
53 | val rotationState by animateFloatAsState(
54 | targetValue = if (expanded) 180f else 0f
55 | )
56 |
57 | Card(modifier = Modifier
58 | .fillMaxWidth()
59 | .animateContentSize(
60 | tween(
61 | durationMillis = if (expanded) durations else durations * 4,
62 | easing = LinearOutSlowInEasing
63 | )
64 | ),
65 | shape = cardShape,
66 | onClick = {
67 | expanded = !expanded
68 | }
69 |
70 | ) {
71 |
72 | Column(
73 | modifier = Modifier
74 | .fillMaxWidth()
75 | .padding(padding)
76 | ) {
77 | Row(verticalAlignment = Alignment.CenterVertically) {
78 | Text(
79 | text = title,
80 | modifier = Modifier.weight(6f),
81 | fontSize = titleFontSize,
82 | fontWeight = titleFontWeight,
83 | maxLines = 1,
84 | overflow = TextOverflow.Ellipsis
85 | )
86 |
87 | IconButton(modifier = Modifier
88 | .weight(1f, true)
89 | .alpha(1.toFloat())
90 | .rotate(rotationState),
91 | onClick = {
92 | expanded = !expanded
93 | }
94 | ) {
95 | Icon(
96 | imageVector = Icons.Default.ArrowDropDown,
97 | contentDescription = "Image Drop Down"
98 | )
99 | }
100 |
101 | }
102 |
103 | if (expanded) {
104 | Text(
105 | text = descriptionText,
106 | modifier = Modifier.fillMaxWidth(),
107 | fontSize = descriptionFontSize,
108 | fontWeight = descriptionFontWeight,
109 | maxLines = descriptionMaxLines,
110 | overflow = TextOverflow.Ellipsis
111 | )
112 | }
113 |
114 | }
115 | }
116 | }
117 |
118 | @Preview(showBackground = true)
119 | @Composable
120 | fun MyPreview() {
121 | SampleComposeAppTheme {
122 | ExpandableCard(
123 | title = "My Title", descriptionText = " Some long text with some long description " +
124 | " Some text here as well to handle the description " +
125 | " lets test and run the app.."
126 | )
127 | }
128 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/modifiers/FocusManagementPractice.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.modifiers
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.border
5 | import androidx.compose.foundation.focusGroup
6 | import androidx.compose.foundation.focusable
7 | import androidx.compose.foundation.layout.Arrangement
8 | import androidx.compose.foundation.layout.Box
9 | import androidx.compose.foundation.layout.Column
10 | import androidx.compose.foundation.layout.fillMaxSize
11 | import androidx.compose.foundation.layout.fillMaxWidth
12 | import androidx.compose.foundation.layout.height
13 | import androidx.compose.foundation.layout.padding
14 | import androidx.compose.foundation.text.KeyboardActions
15 | import androidx.compose.foundation.text.KeyboardOptions
16 | import androidx.compose.material3.Button
17 | import androidx.compose.material3.Text
18 | import androidx.compose.material3.TextField
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.runtime.getValue
21 | import androidx.compose.runtime.mutableStateOf
22 | import androidx.compose.runtime.remember
23 | import androidx.compose.runtime.setValue
24 | import androidx.compose.ui.Alignment
25 | import androidx.compose.ui.Modifier
26 | import androidx.compose.ui.focus.FocusDirection
27 | import androidx.compose.ui.focus.FocusRequester
28 | import androidx.compose.ui.focus.focusRequester
29 | import androidx.compose.ui.focus.onFocusChanged
30 | import androidx.compose.ui.graphics.Color
31 | import androidx.compose.ui.platform.LocalFocusManager
32 | import androidx.compose.ui.text.input.ImeAction
33 | import androidx.compose.ui.tooling.preview.Preview
34 | import androidx.compose.ui.unit.dp
35 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
36 |
37 | @Composable
38 | fun FocusManagementPractice(modifier: Modifier = Modifier) {
39 |
40 | val focusRequester = remember {
41 | FocusRequester()
42 | }
43 | val focusManager = LocalFocusManager.current
44 |
45 | // You can apply focus on TextField..//
46 | Column(
47 | modifier = Modifier.fillMaxSize()
48 | .background(Color.White)
49 | .padding(top = 16.dp),
50 | verticalArrangement = Arrangement.spacedBy(16.dp),
51 | horizontalAlignment = Alignment.CenterHorizontally
52 | ) {
53 | TextField(
54 | value = "",
55 | onValueChange = {
56 |
57 | },
58 | modifier = Modifier
59 | .focusRequester(focusRequester),
60 | keyboardActions = KeyboardActions(
61 | onNext = {
62 | focusManager.moveFocus(FocusDirection.Down)
63 | }
64 | ),
65 | keyboardOptions = KeyboardOptions(
66 | imeAction = ImeAction.Next
67 | )
68 | )
69 | TextField(
70 | value = "",
71 | onValueChange = {
72 |
73 | },
74 | keyboardActions = KeyboardActions(
75 | onNext = {
76 | focusManager.moveFocus(FocusDirection.Down)
77 | }
78 | ),
79 | keyboardOptions = KeyboardOptions(
80 | imeAction = ImeAction.Next
81 | )
82 | )
83 | var isFocused by remember {
84 | mutableStateOf(false)
85 | }
86 | // Box are not by default focusable..//
87 | Box(
88 | modifier = Modifier.fillMaxWidth()
89 | .height(100.dp)
90 | .border(
91 | width = 4.dp,
92 | color = if(isFocused) Color.Red else Color.Green
93 | )
94 | .onFocusChanged {
95 | isFocused = it.isFocused
96 | }
97 | .focusable()
98 | )
99 | TextField(
100 | value = "",
101 | onValueChange = {
102 |
103 | }
104 | )
105 |
106 | // Focus Group..//
107 | Column (
108 | modifier = Modifier.fillMaxWidth()
109 | .border(
110 | width = 4.dp,
111 | color = if(isFocused) Color.Red else Color.Green
112 | )
113 | .onFocusChanged {
114 | isFocused = it.hasFocus
115 | }
116 | .padding(top = 16.dp, bottom = 16.dp)
117 | .focusGroup(),
118 | verticalArrangement = Arrangement.spacedBy(16.dp),
119 | horizontalAlignment = Alignment.CenterHorizontally
120 | ){
121 | TextField(
122 | value = "",
123 | onValueChange = {
124 |
125 | },
126 | modifier = Modifier
127 | .focusRequester(focusRequester),
128 | keyboardActions = KeyboardActions(
129 | onNext = {
130 | focusManager.moveFocus(FocusDirection.Down)
131 | }
132 | ),
133 | keyboardOptions = KeyboardOptions(
134 | imeAction = ImeAction.Next
135 | )
136 | )
137 | TextField(
138 | value = "",
139 | onValueChange = {
140 |
141 | },
142 | keyboardActions = KeyboardActions(
143 | onNext = {
144 | focusManager.moveFocus(FocusDirection.Down)
145 | }
146 | ),
147 | keyboardOptions = KeyboardOptions(
148 | imeAction = ImeAction.Next
149 | )
150 | )
151 | }
152 |
153 | Button(onClick = {
154 | focusRequester.requestFocus()
155 | }) {
156 | Text(text = "Start Filling The Form")
157 | }
158 |
159 | Button(onClick = {
160 | focusManager.clearFocus()
161 | }) {
162 | Text(text = "Clear Focus")
163 | }
164 | }
165 |
166 | }
167 |
168 | @Preview
169 | @Composable
170 | private fun FocusManagementPracticePrev() {
171 | SampleComposeAppTheme {
172 | FocusManagementPractice()
173 | }
174 | }
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | .
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/samplecomposeapp/ui_practice/PracticeScreens/AssignmentScreen.kt:
--------------------------------------------------------------------------------
1 | package com.example.samplecomposeapp.ui_practice.PracticeScreens
2 |
3 | import android.util.Log
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.Arrangement
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.Column
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.Spacer
10 | import androidx.compose.foundation.layout.fillMaxSize
11 | import androidx.compose.foundation.layout.fillMaxWidth
12 | import androidx.compose.foundation.layout.height
13 | import androidx.compose.foundation.layout.heightIn
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.layout.size
16 | import androidx.compose.foundation.layout.width
17 | import androidx.compose.foundation.lazy.LazyColumn
18 | import androidx.compose.foundation.shape.RoundedCornerShape
19 | import androidx.compose.material.icons.Icons
20 | import androidx.compose.material.icons.automirrored.filled.ArrowBack
21 | import androidx.compose.material.icons.filled.Add
22 | import androidx.compose.material.icons.filled.CheckCircle
23 | import androidx.compose.material.icons.filled.MoreVert
24 | import androidx.compose.material.icons.filled.Search
25 | import androidx.compose.material.icons.filled.Settings
26 | import androidx.compose.material.icons.filled.Star
27 | import androidx.compose.material3.BottomAppBar
28 | import androidx.compose.material3.ExperimentalMaterial3Api
29 | import androidx.compose.material3.FloatingActionButton
30 | import androidx.compose.material3.Icon
31 | import androidx.compose.material3.IconButton
32 | import androidx.compose.material3.NavigationBarItem
33 | import androidx.compose.material3.Scaffold
34 | import androidx.compose.material3.SnackbarHost
35 | import androidx.compose.material3.Text
36 | import androidx.compose.material3.TopAppBar
37 | import androidx.compose.runtime.Composable
38 | import androidx.compose.ui.Alignment
39 | import androidx.compose.ui.Modifier
40 | import androidx.compose.ui.draw.alpha
41 | import androidx.compose.ui.draw.clip
42 | import androidx.compose.ui.draw.rotate
43 | import androidx.compose.ui.graphics.Color
44 | import androidx.compose.ui.text.font.FontWeight
45 | import androidx.compose.ui.text.style.TextAlign
46 | import androidx.compose.ui.text.style.TextOverflow
47 | import androidx.compose.ui.tooling.preview.Preview
48 | import androidx.compose.ui.tooling.preview.PreviewScreenSizes
49 | import androidx.compose.ui.unit.dp
50 | import androidx.compose.ui.unit.sp
51 | import com.example.samplecomposeapp.ui.theme.SampleComposeAppTheme
52 | import kotlinx.coroutines.launch
53 |
54 | @Composable
55 | fun AssignmentScreen(notificationItem: NotificationItem,modifier: Modifier = Modifier) {
56 | LazyColumn(
57 | modifier = modifier
58 | .fillMaxSize()
59 | .background(Color.White),
60 | verticalArrangement = Arrangement.spacedBy(16.dp)){
61 | item {
62 | NotificationCard(notificationItem)
63 | }
64 | }
65 | }
66 |
67 |
68 | @Composable
69 | fun NotificationCard(notificationItem: NotificationItem,modifier: Modifier = Modifier) {
70 | Column (
71 | modifier = Modifier
72 | .padding(
73 | top = 45.dp,
74 | start = 8.dp, end = 8.dp
75 | )
76 | .clip(RoundedCornerShape(6.dp))
77 | .background(Color.Red)
78 | .fillMaxSize()
79 | .heightIn(
80 | min = 150.dp,
81 | max = 200.dp
82 | )
83 | ){
84 | Row(modifier = Modifier
85 | .padding(16.dp)
86 | .fillMaxWidth(),
87 | horizontalArrangement = Arrangement.spacedBy(12.dp),
88 | verticalAlignment = Alignment.CenterVertically
89 | ) {
90 | Icon(
91 | imageVector = Icons.Default.CheckCircle,
92 | contentDescription = null,
93 | tint = Color.White
94 | )
95 |
96 | Text(text = "Project X",
97 | color = Color.White,
98 | fontSize = 32.sp,
99 | modifier = Modifier
100 | .weight(1f)
101 | )
102 |
103 | Icon(
104 | imageVector = Icons.Default.MoreVert,
105 | contentDescription = null,
106 | tint = Color.White,
107 | modifier = Modifier.rotate(90f)
108 |
109 | )
110 | }
111 |
112 | Row(modifier = Modifier
113 | .fillMaxWidth(),
114 | horizontalArrangement = Arrangement.spacedBy(12.dp),
115 | verticalAlignment = Alignment.CenterVertically
116 | ) {
117 | Icon(
118 | imageVector = Icons.Default.CheckCircle,
119 | contentDescription = null,
120 | tint = Color.White,
121 | modifier = Modifier.alpha(0f)
122 | )
123 |
124 | Text(text = "This is a short Description",
125 | color = Color.White,
126 | fontSize = 20.sp,
127 | modifier = Modifier
128 | .fillMaxWidth()
129 | .weight(1f)
130 | )
131 | Icon(
132 | imageVector = Icons.Default.MoreVert,
133 | contentDescription = null,
134 | tint = Color.White,
135 | modifier = Modifier.rotate(90f)
136 | .alpha(0f)
137 | )
138 | }
139 |
140 |
141 | Text(text = "Mar 5, 10:00",
142 | color = Color.White,
143 | fontSize = 24.sp,
144 | modifier = Modifier
145 | .fillMaxWidth()
146 | .padding(top = 8.dp,
147 | end = 8.dp),
148 | textAlign = TextAlign.End
149 | )
150 |
151 |
152 | }
153 | }
154 |
155 |
156 | @PreviewScreenSizes
157 | @Preview(showBackground = true)
158 | @Composable
159 | fun AssignmentScreenPreview() {
160 | SampleComposeAppTheme {
161 | AssignmentScreen(
162 | notificationItem = NotificationItem(
163 | title = "My notification",
164 | text = """
165 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed et est tellus. Donec placerat sodales arcu. Quisque malesuada iaculis est. Sed vestibulum enim est, eu venenatis eros egestas rhoncus. Praesent nec quam ipsum. Phasellus venenatis placerat enim, nec rhoncus nunc pretium quis. In id tincidunt purus. Donec pretium, magna hendrerit feugiat suscipit, nibh sem efficitur arcu, quis tempus mi felis id diam. Quisque tempor enim a est tempus, eget interdum eros ultricies. Aliquam fringilla rutrum sapien ut elementum. Sed consectetur justo lorem, sit amet hendrerit tortor tincidunt sed. Nulla dolor ligula, lobortis ut dapibus id, varius eu massa. Nullam ut pharetra dolor, id feugiat nisi. Suspendisse a lorem neque. Proin et sapien eu tortor venenatis tincidunt et et orci. Aliquam erat volutpat.
166 | """.trimIndent(),
167 | date = "Jan 5, 11:45"
168 | )
169 | )
170 | }
171 | }
172 |
173 | data class NotificationItem (val title:String, val text:String, val date:String)
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.7)
5 | base64
6 | nkf
7 | rexml
8 | addressable (2.8.7)
9 | public_suffix (>= 2.0.2, < 7.0)
10 | artifactory (3.0.17)
11 | atomos (0.1.3)
12 | aws-eventstream (1.3.0)
13 | aws-partitions (1.1018.0)
14 | aws-sdk-core (3.214.0)
15 | aws-eventstream (~> 1, >= 1.3.0)
16 | aws-partitions (~> 1, >= 1.992.0)
17 | aws-sigv4 (~> 1.9)
18 | jmespath (~> 1, >= 1.6.1)
19 | aws-sdk-kms (1.96.0)
20 | aws-sdk-core (~> 3, >= 3.210.0)
21 | aws-sigv4 (~> 1.5)
22 | aws-sdk-s3 (1.176.0)
23 | aws-sdk-core (~> 3, >= 3.210.0)
24 | aws-sdk-kms (~> 1)
25 | aws-sigv4 (~> 1.5)
26 | aws-sigv4 (1.10.1)
27 | aws-eventstream (~> 1, >= 1.0.2)
28 | babosa (1.0.4)
29 | base64 (0.2.0)
30 | claide (1.1.0)
31 | colored (1.2)
32 | colored2 (3.1.2)
33 | commander (4.6.0)
34 | highline (~> 2.0.0)
35 | declarative (0.0.20)
36 | digest-crc (0.6.5)
37 | rake (>= 12.0.0, < 14.0.0)
38 | domain_name (0.6.20240107)
39 | dotenv (2.8.1)
40 | emoji_regex (3.2.3)
41 | excon (0.112.0)
42 | faraday (1.10.4)
43 | faraday-em_http (~> 1.0)
44 | faraday-em_synchrony (~> 1.0)
45 | faraday-excon (~> 1.1)
46 | faraday-httpclient (~> 1.0)
47 | faraday-multipart (~> 1.0)
48 | faraday-net_http (~> 1.0)
49 | faraday-net_http_persistent (~> 1.0)
50 | faraday-patron (~> 1.0)
51 | faraday-rack (~> 1.0)
52 | faraday-retry (~> 1.0)
53 | ruby2_keywords (>= 0.0.4)
54 | faraday-cookie_jar (0.0.7)
55 | faraday (>= 0.8.0)
56 | http-cookie (~> 1.0.0)
57 | faraday-em_http (1.0.0)
58 | faraday-em_synchrony (1.0.0)
59 | faraday-excon (1.1.0)
60 | faraday-httpclient (1.0.1)
61 | faraday-multipart (1.0.4)
62 | multipart-post (~> 2)
63 | faraday-net_http (1.0.2)
64 | faraday-net_http_persistent (1.2.0)
65 | faraday-patron (1.0.0)
66 | faraday-rack (1.0.0)
67 | faraday-retry (1.0.3)
68 | faraday_middleware (1.2.1)
69 | faraday (~> 1.0)
70 | fastimage (2.3.1)
71 | fastlane (2.225.0)
72 | CFPropertyList (>= 2.3, < 4.0.0)
73 | addressable (>= 2.8, < 3.0.0)
74 | artifactory (~> 3.0)
75 | aws-sdk-s3 (~> 1.0)
76 | babosa (>= 1.0.3, < 2.0.0)
77 | bundler (>= 1.12.0, < 3.0.0)
78 | colored (~> 1.2)
79 | commander (~> 4.6)
80 | dotenv (>= 2.1.1, < 3.0.0)
81 | emoji_regex (>= 0.1, < 4.0)
82 | excon (>= 0.71.0, < 1.0.0)
83 | faraday (~> 1.0)
84 | faraday-cookie_jar (~> 0.0.6)
85 | faraday_middleware (~> 1.0)
86 | fastimage (>= 2.1.0, < 3.0.0)
87 | fastlane-sirp (>= 1.0.0)
88 | gh_inspector (>= 1.1.2, < 2.0.0)
89 | google-apis-androidpublisher_v3 (~> 0.3)
90 | google-apis-playcustomapp_v1 (~> 0.1)
91 | google-cloud-env (>= 1.6.0, < 2.0.0)
92 | google-cloud-storage (~> 1.31)
93 | highline (~> 2.0)
94 | http-cookie (~> 1.0.5)
95 | json (< 3.0.0)
96 | jwt (>= 2.1.0, < 3)
97 | mini_magick (>= 4.9.4, < 5.0.0)
98 | multipart-post (>= 2.0.0, < 3.0.0)
99 | naturally (~> 2.2)
100 | optparse (>= 0.1.1, < 1.0.0)
101 | plist (>= 3.1.0, < 4.0.0)
102 | rubyzip (>= 2.0.0, < 3.0.0)
103 | security (= 0.1.5)
104 | simctl (~> 1.6.3)
105 | terminal-notifier (>= 2.0.0, < 3.0.0)
106 | terminal-table (~> 3)
107 | tty-screen (>= 0.6.3, < 1.0.0)
108 | tty-spinner (>= 0.8.0, < 1.0.0)
109 | word_wrap (~> 1.0.0)
110 | xcodeproj (>= 1.13.0, < 2.0.0)
111 | xcpretty (~> 0.3.0)
112 | xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
113 | fastlane-sirp (1.0.0)
114 | sysrandom (~> 1.0)
115 | gh_inspector (1.1.3)
116 | google-apis-androidpublisher_v3 (0.54.0)
117 | google-apis-core (>= 0.11.0, < 2.a)
118 | google-apis-core (0.11.3)
119 | addressable (~> 2.5, >= 2.5.1)
120 | googleauth (>= 0.16.2, < 2.a)
121 | httpclient (>= 2.8.1, < 3.a)
122 | mini_mime (~> 1.0)
123 | representable (~> 3.0)
124 | retriable (>= 2.0, < 4.a)
125 | rexml
126 | google-apis-iamcredentials_v1 (0.17.0)
127 | google-apis-core (>= 0.11.0, < 2.a)
128 | google-apis-playcustomapp_v1 (0.13.0)
129 | google-apis-core (>= 0.11.0, < 2.a)
130 | google-apis-storage_v1 (0.31.0)
131 | google-apis-core (>= 0.11.0, < 2.a)
132 | google-cloud-core (1.7.1)
133 | google-cloud-env (>= 1.0, < 3.a)
134 | google-cloud-errors (~> 1.0)
135 | google-cloud-env (1.6.0)
136 | faraday (>= 0.17.3, < 3.0)
137 | google-cloud-errors (1.4.0)
138 | google-cloud-storage (1.47.0)
139 | addressable (~> 2.8)
140 | digest-crc (~> 0.4)
141 | google-apis-iamcredentials_v1 (~> 0.1)
142 | google-apis-storage_v1 (~> 0.31.0)
143 | google-cloud-core (~> 1.6)
144 | googleauth (>= 0.16.2, < 2.a)
145 | mini_mime (~> 1.0)
146 | googleauth (1.8.1)
147 | faraday (>= 0.17.3, < 3.a)
148 | jwt (>= 1.4, < 3.0)
149 | multi_json (~> 1.11)
150 | os (>= 0.9, < 2.0)
151 | signet (>= 0.16, < 2.a)
152 | highline (2.0.3)
153 | http-cookie (1.0.8)
154 | domain_name (~> 0.5)
155 | httpclient (2.8.3)
156 | jmespath (1.6.2)
157 | json (2.9.0)
158 | jwt (2.9.3)
159 | base64
160 | mini_magick (4.13.2)
161 | mini_mime (1.1.5)
162 | multi_json (1.15.0)
163 | multipart-post (2.4.1)
164 | nanaimo (0.4.0)
165 | naturally (2.2.1)
166 | nkf (0.2.0)
167 | optparse (0.6.0)
168 | os (1.1.4)
169 | plist (3.7.1)
170 | public_suffix (6.0.1)
171 | rake (13.2.1)
172 | representable (3.2.0)
173 | declarative (< 0.1.0)
174 | trailblazer-option (>= 0.1.1, < 0.2.0)
175 | uber (< 0.2.0)
176 | retriable (3.1.2)
177 | rexml (3.3.9)
178 | rouge (2.0.7)
179 | ruby2_keywords (0.0.5)
180 | rubyzip (2.3.2)
181 | security (0.1.5)
182 | signet (0.19.0)
183 | addressable (~> 2.8)
184 | faraday (>= 0.17.5, < 3.a)
185 | jwt (>= 1.5, < 3.0)
186 | multi_json (~> 1.10)
187 | simctl (1.6.10)
188 | CFPropertyList
189 | naturally
190 | sysrandom (1.0.5)
191 | terminal-notifier (2.0.0)
192 | terminal-table (3.0.2)
193 | unicode-display_width (>= 1.1.1, < 3)
194 | trailblazer-option (0.1.2)
195 | tty-cursor (0.7.1)
196 | tty-screen (0.8.2)
197 | tty-spinner (0.9.3)
198 | tty-cursor (~> 0.7)
199 | uber (0.1.0)
200 | unicode-display_width (2.6.0)
201 | word_wrap (1.0.0)
202 | xcodeproj (1.27.0)
203 | CFPropertyList (>= 2.3.3, < 4.0)
204 | atomos (~> 0.1.3)
205 | claide (>= 1.0.2, < 2.0)
206 | colored2 (~> 3.1)
207 | nanaimo (~> 0.4.0)
208 | rexml (>= 3.3.6, < 4.0)
209 | xcpretty (0.3.0)
210 | rouge (~> 2.0.7)
211 | xcpretty-travis-formatter (1.0.1)
212 | xcpretty (~> 0.2, >= 0.0.7)
213 |
214 | PLATFORMS
215 | arm64-darwin-23
216 | ruby
217 |
218 | DEPENDENCIES
219 | fastlane
220 |
221 | BUNDLED WITH
222 | 2.5.23
223 |
--------------------------------------------------------------------------------