From b2c1b57fe05b0e831ac516f14d7febb35fe485b3 Mon Sep 17 00:00:00 2001 From: shabinder Date: Tue, 29 Dec 2020 12:46:25 +0530 Subject: [PATCH] Theming, App bar,Home Screen tabs. --- app/build.gradle | 5 +- .../composelearn/ExampleInstrumentedTest.kt | 24 --- app/src/main/AndroidManifest.xml | 6 +- .../spotiflyer}/MainActivity.kt | 44 +++--- .../com/shabinder/spotiflyer/home/Home.kt | 148 ++++++++++++++++++ .../spotiflyer/home/HomeViewModel.kt | 39 +++++ .../spotiflyer}/ui/Color.kt | 6 +- .../spotiflyer}/ui/Shape.kt | 2 +- .../spotiflyer}/ui/Theme.kt | 2 +- .../spotiflyer}/ui/Type.kt | 10 +- app/src/main/res/values/strings.xml | 2 + app/src/main/res/values/themes.xml | 3 +- .../example/composelearn/ExampleUnitTest.kt | 17 -- build.gradle | 21 ++- settings.gradle | 2 +- 15 files changed, 248 insertions(+), 83 deletions(-) delete mode 100644 app/src/androidTest/java/com/example/composelearn/ExampleInstrumentedTest.kt rename app/src/main/java/com/{example/composelearn => shabinder/spotiflyer}/MainActivity.kt (74%) create mode 100644 app/src/main/java/com/shabinder/spotiflyer/home/Home.kt create mode 100644 app/src/main/java/com/shabinder/spotiflyer/home/HomeViewModel.kt rename app/src/main/java/com/{example/composelearn => shabinder/spotiflyer}/ui/Color.kt (88%) rename app/src/main/java/com/{example/composelearn => shabinder/spotiflyer}/ui/Shape.kt (89%) rename app/src/main/java/com/{example/composelearn => shabinder/spotiflyer}/ui/Theme.kt (90%) rename app/src/main/java/com/{example/composelearn => shabinder/spotiflyer}/ui/Type.kt (95%) delete mode 100644 app/src/test/java/com/example/composelearn/ExampleUnitTest.kt diff --git a/app/build.gradle b/app/build.gradle index 28cf2a1b..f27d39f1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ android { buildToolsVersion "30.0.3" defaultConfig { - applicationId "com.example.composelearn" + applicationId "com.shabinder.spotiflyer" minSdkVersion 22 targetSdkVersion 30 versionCode 1 @@ -75,9 +75,10 @@ dependencies { //Compose implementation "androidx.compose.ui:ui:$compose_version" + implementation "androidx.compose.ui:ui-tooling:$compose_version" + implementation "androidx.compose.runtime:runtime-livedata:$compose_version" implementation "androidx.compose.material:material:$compose_version" implementation "androidx.compose.material:material-icons-extended:$compose_version" - implementation "androidx.compose.ui:ui-tooling:$compose_version" //Lifecycle implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" diff --git a/app/src/androidTest/java/com/example/composelearn/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/composelearn/ExampleInstrumentedTest.kt deleted file mode 100644 index 86e089c6..00000000 --- a/app/src/androidTest/java/com/example/composelearn/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.composelearn - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.example.composelearn", appContext.packageName) - } -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d8ab2498..70824052 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.shabinder.spotiflyer"> + android:theme="@style/Theme.SpotiFlyer"> + android:theme="@style/Theme.SpotiFlyer"> diff --git a/app/src/main/java/com/example/composelearn/MainActivity.kt b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt similarity index 74% rename from app/src/main/java/com/example/composelearn/MainActivity.kt rename to app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt index d13d1f80..471bb7d4 100644 --- a/app/src/main/java/com/example/composelearn/MainActivity.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt @@ -1,4 +1,4 @@ -package com.example.composelearn +package com.shabinder.spotiflyer import android.os.Bundle import androidx.appcompat.app.AppCompatActivity @@ -15,11 +15,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.setContent import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat -import com.example.composelearn.ui.ComposeLearnTheme -import com.example.composelearn.ui.appNameStyle +import com.shabinder.spotiflyer.home.Home +import com.shabinder.spotiflyer.ui.ComposeLearnTheme +import com.shabinder.spotiflyer.ui.appNameStyle import dev.chrisbanes.accompanist.insets.ProvideWindowInsets import dev.chrisbanes.accompanist.insets.statusBarsHeight @@ -33,28 +32,23 @@ class MainActivity : AppCompatActivity() { setContent { ComposeLearnTheme { ProvideWindowInsets { - HomeScreen() + Column { + val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.87f) + + // Draw a scrim over the status bar which matches the app bar + Spacer(Modifier.background(appBarColor).fillMaxWidth().statusBarsHeight()) + + AppBar( + backgroundColor = appBarColor, + modifier = Modifier.fillMaxWidth() + ) + + Home() + } } } } } - - -} - -@Composable -fun HomeScreen() { - Column { - val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.87f) - - // Draw a scrim over the status bar which matches the app bar - Spacer(Modifier.background(appBarColor).fillMaxWidth().statusBarsHeight()) - - AppBar( - backgroundColor = appBarColor, - modifier = Modifier.fillMaxWidth() - ) - } } @Composable @@ -89,10 +83,10 @@ fun AppBar( } -@Preview(showBackground = true) +//@Preview(showBackground = true) @Composable fun DefaultPreview() { ComposeLearnTheme { - HomeScreen() + } } \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/home/Home.kt b/app/src/main/java/com/shabinder/spotiflyer/home/Home.kt new file mode 100644 index 00000000..c36604d8 --- /dev/null +++ b/app/src/main/java/com/shabinder/spotiflyer/home/Home.kt @@ -0,0 +1,148 @@ +package com.shabinder.spotiflyer.home + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.* +import androidx.compose.material.TabDefaults.tabIndicatorOffset +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.InsertLink +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.viewinterop.viewModel +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.shabinder.spotiflyer.R +import com.shabinder.spotiflyer.ui.SpotiFlyerTypography +import com.shabinder.spotiflyer.ui.colorAccent +import com.shabinder.spotiflyer.ui.colorPrimary + +@Composable +fun Home(modifier: Modifier = Modifier) { + val viewModel: HomeViewModel = viewModel() + + Column(modifier = modifier) { + + AuthenticationBanner(viewModel,modifier) + SearchBar(viewModel,modifier) + + val selectedCategory by viewModel.selectedCategory.collectAsState() + + HomeTabBar( + selectedCategory, + HomeCategory.values(), + viewModel::selectCategory, + modifier + ) + + } +} + +@Composable +fun AuthenticationBanner(viewModel: HomeViewModel, modifier: Modifier) { + val authenticationStatus by viewModel.isAuthenticating.collectAsState() + + if (authenticationStatus) { + // TODO show a progress indicator or similar + } +} + +@Composable +fun HomeTabBar( + selectedCategory: HomeCategory, + categories: Array, + selectCategory: (HomeCategory) -> Unit, + modifier: Modifier = Modifier +) { + val selectedIndex =categories.indexOfFirst { it == selectedCategory } + val indicator = @Composable { tabPositions: List -> + HomeCategoryTabIndicator( + Modifier.tabIndicatorOffset(tabPositions[selectedIndex]) + ) + } + + TabRow( + selectedTabIndex = selectedIndex, + indicator = indicator, + modifier = modifier + ) { + categories.forEachIndexed { index, category -> + Tab( + selected = index == selectedIndex, + onClick = { selectCategory(category) }, + text = { + Text( + text = when (category) { + HomeCategory.About -> stringResource(R.string.home_about) + HomeCategory.History -> stringResource(R.string.home_history) + }, + style = MaterialTheme.typography.body2 + ) + } + ) + } + } +} + +@Composable +fun SearchBar( + viewModel: HomeViewModel, + modifier: Modifier = Modifier +){ + val link by viewModel.link.collectAsState() + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = modifier.padding(top = 16.dp,bottom = 16.dp) + ){ + TextField( + leadingIcon = { + Icon(Icons.Rounded.InsertLink,tint = Color.LightGray) + }, + label = {Text(text = "Paste Link Here...",color = Color.LightGray)}, + value = link, + onValueChange = { viewModel.updateLink(it) }, + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri), + modifier = Modifier.padding(12.dp).fillMaxWidth() + .border( + BorderStroke(2.dp, Brush.horizontalGradient(listOf(colorPrimary, colorAccent))), + RoundedCornerShape(30.dp) + ), + backgroundColor = Color.Black, + textStyle = AmbientTextStyle.current.merge(TextStyle(fontSize = 20.sp)), + shape = RoundedCornerShape(size = 30.dp), + activeColor = Color.Transparent, + inactiveColor = Color.Transparent + ) + OutlinedButton( + modifier = Modifier.padding(12.dp).wrapContentWidth(), + onClick = {/*TODO*/}, + border = BorderStroke(1.dp, Brush.horizontalGradient(listOf(colorPrimary, colorAccent))) + ){ + Text(text = "Search",style = SpotiFlyerTypography.h6,modifier = Modifier.padding(4.dp)) + } + } +} +@Composable +fun HomeCategoryTabIndicator( + modifier: Modifier = Modifier, + color: Color = MaterialTheme.colors.onSurface +) { + Spacer( + modifier.padding(horizontal = 24.dp) + .preferredHeight(4.dp) + .background(color, RoundedCornerShape(topLeftPercent = 100, topRightPercent = 100)) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/home/HomeViewModel.kt b/app/src/main/java/com/shabinder/spotiflyer/home/HomeViewModel.kt new file mode 100644 index 00000000..4c8d855f --- /dev/null +++ b/app/src/main/java/com/shabinder/spotiflyer/home/HomeViewModel.kt @@ -0,0 +1,39 @@ +package com.shabinder.spotiflyer.home + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + +class HomeViewModel: ViewModel() { + + private val _link = MutableStateFlow("") + val link:StateFlow + get() = _link + + fun updateLink(s:String) { + _link.value = s + } + + private val _isAuthenticating = MutableStateFlow(true) + val isAuthenticating:StateFlow + get() = _isAuthenticating + + fun authenticated(s:Boolean) { + _isAuthenticating.value = s + } + + private val _selectedCategory = MutableStateFlow(HomeCategory.About) + val selectedCategory :StateFlow + get() = _selectedCategory + + fun selectCategory(s:HomeCategory) { + _selectedCategory.value = s + } + +} + +enum class HomeCategory { + About, History +} \ No newline at end of file diff --git a/app/src/main/java/com/example/composelearn/ui/Color.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/Color.kt similarity index 88% rename from app/src/main/java/com/example/composelearn/ui/Color.kt rename to app/src/main/java/com/shabinder/spotiflyer/ui/Color.kt index 2673ef67..fe34eeac 100644 --- a/app/src/main/java/com/example/composelearn/ui/Color.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/Color.kt @@ -1,4 +1,4 @@ -package com.example.composelearn.ui +package com.shabinder.spotiflyer.ui import androidx.compose.material.Colors import androidx.compose.material.darkColors @@ -22,7 +22,9 @@ val SpotiFlyerColors = darkColors( error = colorRedError, onError = Color.Black, surface = darkBackgroundColor, - background = darkBackgroundColor + background = darkBackgroundColor, + onSurface = Color.LightGray, + onBackground = Color.LightGray ) /** diff --git a/app/src/main/java/com/example/composelearn/ui/Shape.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/Shape.kt similarity index 89% rename from app/src/main/java/com/example/composelearn/ui/Shape.kt rename to app/src/main/java/com/shabinder/spotiflyer/ui/Shape.kt index fd2dc14e..585664e2 100644 --- a/app/src/main/java/com/example/composelearn/ui/Shape.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/Shape.kt @@ -1,4 +1,4 @@ -package com.example.composelearn.ui +package com.shabinder.spotiflyer.ui import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Shapes diff --git a/app/src/main/java/com/example/composelearn/ui/Theme.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/Theme.kt similarity index 90% rename from app/src/main/java/com/example/composelearn/ui/Theme.kt rename to app/src/main/java/com/shabinder/spotiflyer/ui/Theme.kt index c7c4252a..e0650985 100644 --- a/app/src/main/java/com/example/composelearn/ui/Theme.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/Theme.kt @@ -1,4 +1,4 @@ -package com.example.composelearn.ui +package com.shabinder.spotiflyer.ui import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable diff --git a/app/src/main/java/com/example/composelearn/ui/Type.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/Type.kt similarity index 95% rename from app/src/main/java/com/example/composelearn/ui/Type.kt rename to app/src/main/java/com/shabinder/spotiflyer/ui/Type.kt index 40651fef..580a976e 100644 --- a/app/src/main/java/com/example/composelearn/ui/Type.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/Type.kt @@ -1,11 +1,11 @@ -package com.example.composelearn.ui +package com.shabinder.spotiflyer.ui import androidx.compose.material.Typography import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.* import androidx.compose.ui.unit.sp -import com.example.composelearn.R +import com.shabinder.spotiflyer.R private val Montserrat = fontFamily( font(R.font.montserrat_light, FontWeight.Light), @@ -110,9 +110,9 @@ val SpotiFlyerTypography = Typography( val appNameStyle = TextStyle( fontFamily = pristineFont, - fontSize = 42.sp, + fontSize = 40.sp, fontWeight = FontWeight.SemiBold, lineHeight = 42.sp, - letterSpacing = (-0.5).sp, - color = Color.White + letterSpacing = (1.5).sp, + color = Color(0xFFECECEC) ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 723929bb..bc78f2e4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ SpotiFlyer + About + History \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 04c03af1..52f9b65a 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,9 +1,10 @@ - diff --git a/app/src/test/java/com/example/composelearn/ExampleUnitTest.kt b/app/src/test/java/com/example/composelearn/ExampleUnitTest.kt deleted file mode 100644 index 3a78da6c..00000000 --- a/app/src/test/java/com/example/composelearn/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.composelearn - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/build.gradle b/build.gradle index ed1597dd..ae12ba7e 100644 --- a/build.gradle +++ b/build.gradle @@ -23,12 +23,31 @@ buildscript { } } -allprojects { +subprojects{ repositories { google() jcenter() maven { url "https://jitpack.io" } } + + tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { + kotlinOptions { + // Treat all Kotlin warnings as errors + //allWarningsAsErrors = true + + freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn' + + // Enable experimental coroutines APIs, including Flow + freeCompilerArgs += '-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi' + freeCompilerArgs += '-Xopt-in=kotlinx.coroutines.FlowPreview' + freeCompilerArgs += '-Xopt-in=kotlin.Experimental' + + freeCompilerArgs += "-Xallow-jvm-ir-dependencies" + + // Set JVM target to 1.8 + jvmTarget = "1.8" + } + } } task clean(type: Delete) { diff --git a/settings.gradle b/settings.gradle index 6a496cb1..e262e3cc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -rootProject.name = "ComposeLearn" +rootProject.name = "SpotiFlyer" include ':app'