Jetpack Compose - Part 4

Jetpack Compose - Part 4

In this article will learn about few more UI components which are widely used in Android app development.

To implement a search bar in the app UI, we can use Material component "Text Field".

Inside the composable function implement basic Text field component as shown below.

@Composable
fun SearchBar(modifier: Modifier = Modifier){
   TextField(value = "",
       onValueChange ={},
       leadingIcon = {
             Icon(imageVector = Icons.Default.Search , contentDescription = null)
       },
       placeholder = {
           Text(stringResource(id = R.string.placeholder_search))
       },
       colors = TextFieldDefaults.colors(
           unfocusedContainerColor = MaterialTheme.colorScheme.surface
       ),
       modifier= Modifier.fillMaxWidth().height(56.dp))

}

@Preview(showBackground = true, backgroundColor = 0xFFF5F0EE)
@Composable
fun SearchBarPreview(){
    JetpackComposeBasicsTheme {
        SearchBar(modifier= Modifier.padding(16.dp))
    }

Bottom Navigation

Navigation bar helps the user switch between screens. Compose material library provides NavigationBar composable, in which, we need to add NavigationBarItem elements which will get styled automatically by the material library.

Below example shows simple implementation of Navigation bar in compose.

@Composable
fun BottomNavigationBar(modifier: Modifier = Modifier){

    NavigationBar(modifier= modifier){
          NavigationBarItem(selected = true,
              onClick = {  },
              icon = { Icon(imageVector = Icons.Default.Home,null)},
              label= {Text(text= stringResource(R.string.btm_navigation_home))})
             NavigationBarItem(selected = false,
              onClick = {  },
              icon = { Icon(imageVector = Icons.Default.List,null)},
              label= {Text(text= stringResource(R.string.btm_navigation_flowers))})
    }
}

@Preview(showBackground = true, backgroundColor = 0xFFF5F0EE)
@Composable
fun PreviewNavigation(){
  JetpackComposeBasicsTheme {
      BottomNavigationBar(Modifier.padding(top=24.dp))
  }
}

Navigation Rail

In landscape mode, bottom navigation turns into rail on the left side of the screen. This can be implemented similar to bottom navigation but using NavigationRail composable. Inside this composable NavigationRailItem elements should be included.

@Composable
fun NavigationRailFun(modifier: Modifier = Modifier){

    NavigationRail( modifier= modifier.padding(start=8.dp,end=8.dp),
        containerColor= MaterialTheme.colorScheme.background){
       Column(modifier= Modifier.fillMaxHeight(),
              verticalArrangement = Arrangement.Center,
           horizontalAlignment = Alignment.CenterHorizontally) {
           NavigationRailItem(selected = true,
               onClick = {  },
               icon = { Icon(imageVector = Icons.Default.Home,null)},
               label= {Text(text= stringResource(R.string.btm_navigation_home))})
           NavigationRailItem(selected = false,
               onClick = {  },
               icon = { Icon(imageVector = Icons.Default.List,null)},
               label= {Text(text= stringResource(R.string.btm_navigation_flowers))})
       }

    }
}

@Preview(showBackground = true, backgroundColor = 0xFFF5F0EE)
@Composable
fun PreviewNavigationRailFun(){
    JetpackComposeBasicsTheme {
        NavigationRailFun()
    }
}

Calculate Window Size Class

During app development another important thing to consider is - the screen configuration. Based on whether the phone is in portrait mode or landscape mode we need to send instructions to use the correct composables. To check the configuration we can use calculateWindowSizeClass().

Note - calculateWindowSize() is still experimental, hence we need to opt into ExperimentalMaterial3WindowSizeClassApi.

While invoking the composable function, check the phone configuration/size and pass it as a parameter as shown below.

import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass

class MainActivity : ComponentActivity() {
   @OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           val windowSizeClass = calculateWindowSizeClass(this)
           MyTestApp(windowSizeClass)
       }
   }
}

Based on the window size passed, further invoke the right composables to get the perfect output. Below logic can be used.

import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
@Composable
fun MyTestApp(windowSize: WindowSizeClass) {
   when (windowSize.widthSizeClass) {
       WindowWidthSizeClass.Compact -> {
           MyTestAppPortrait()
       }
       WindowWidthSizeClass.Expanded -> {
           MyTestAppLandscape()
       }
   }
}

Conclusion

Compose provides lot of powerful tools to create beautiful interactive UIs. I am also new to compose, as and when I learn/try something new with compose, will keep posting the articles. Happy Composing.