0%
Loading ...

Jetpack Compose Basics

Jetpack Compose Basics

Card in Jetpack Compose

Cards are an essential component in modern user interfaces, providing a visually appealing way to present information and content. In Jetpack Compose, Google's declarative UI toolkit for Android app development, the Card component offers a powerful and flexible solution for creating beautiful cards. In this article, we will explore the various properties of the Card component, including elevation, background, and corner radius. By understanding these properties, you'll be able to design stunning and engaging user interfaces. Understanding the Card Component: The Card component in Jetpack Compose allows you to create cards with customizable styles and behaviours. Let's delve into the key properties of the Card component and see how they can be used to enhance your UI. Elevation: The elevation property of the Card the component determines the visual depth and shadow effect applied to the card. By adjusting the elevation value, you can create a sense of depth and highlight important elements in your UI. Higher elevation values result in stronger shadows. Example 1: Applying Elevation to a Card: Card( elevation = 4.dp, modifier = Modifier.padding(16.dp) ) { // Card content goes here } Example 2: Dynamic Elevation with Animation: val animateElevation by animateDpAsState(targetValue = if (isHovered) 8.dp else 4.dp) Card( elevation = animateElevation, modifier = Modifier .padding(16.dp) .hoverable { isHovered = it } ) { // Card content goes here } Background: The background property of the Card component allows you to define a custom background colour or drawable for the card. You can use solid colours, gradients, or even images to create visually distinct and engaging cards. Example: Custom Background for a Card: Card( elevation = 4.dp, background = Color.LightBlue, modifier = Modifier.padding(16.dp) ) { // Card content goes here } Corner Radius: The shape property of the Card component enables you to specify the corner radius of the card. By adjusting the corner radius, you can create cards with rounded or sharp corners, depending on your design needs. Example 1: Rounded Corner Card: Card( elevation = 4.dp, shape = RoundedCornerShape(8.dp), modifier = Modifier.padding(16.dp) ) { // Card content goes here } Example 2: Custom Shape with Different Corner Radius: Card( elevation = 4.dp, shape = RoundedCornerShape(topStart = 8.dp, topEnd = 24.dp, bottomEnd = 8.dp, bottomStart = 24.dp), modifier = Modifier.padding(16.dp) ) { // Card content goes here } Conclusion: In this article, we explored the various properties of the Card component in Jetpack Compose, allowing you to create visually appealing and customizable cards. By utilizing properties such as elevation, background, and corner radius, you can elevate your UI and design stunning user interfaces. Remember to experiment with different values and combinations to achieve the desired visual effects for your cards. Jetpack Compose's Card component empowers you to create stylish and engaging user interfaces that capture the attention of your users. Embrace the flexibility and customization options provided by the Card component to design remarkable card-based layouts in your Android applications. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

Card in Jetpack Compose Read More »

Icon in Compose

Icons play a vital role in modern user interfaces, effectively conveying information and enhancing the overall user experience. In Jetpack Compose, Google's modern UI toolkit for Android app development, the Icon component provides a flexible and powerful way to incorporate icons into your applications. In this article, we will delve into the various properties of the Icon component, including tint and size, enabling you to create visually appealing and intuitive user interfaces. Understanding the Icon Component: The Icon component in Jetpack Compose allows you to display vector-based icons in your app. These icons are highly customizable and easily scaled and styled according to your design requirements. Let's explore the key properties of the Icon component. Tint: The tint property of the Icon the component enables you to apply colour to the icon. Specifying a colour value allows you to seamlessly integrate the icon with the surrounding UI elements, maintaining visual harmony. For instance, you can use tint = Color.Red to apply a red tint to the icon, or you can use tint = Color.Transparent to create a transparent effect. Example 1: Applying Tint to an Icon Icon( imageVector = Icons.Filled.Favorite, contentDescription = “Favorite”, tint = Color.Red, modifier = Modifier.size(48.dp) ) Example 2: Applying a Dynamic Tint to an Icon val selected = remember { mutableStateOf(false) } Icon( imageVector = Icons.Filled.Star, contentDescription = “Star”, tint = if (selected.value) Color.Yellow else Color.Gray, modifier = Modifier.size(24.dp).clickable { selected.value = !selected.value } ) Size: The size property of the Icon component allows you to control the dimensions of the icon. You can specify the size using various units like dp (density-independent pixels), sp (scaled pixels), or em (relative to the font size). By adjusting the size, you can ensure the icon fits perfectly within your layout. Example 1: Controlling Icon Size Icon( imageVector = Icons.Filled.ArrowBack, contentDescription = “Back”, tint = Color.Black, modifier = Modifier.size(32.dp) ) Example 2: Dynamic Icon Size val iconSize = remember { mutableStateOf(24.dp) } Icon( imageVector = Icons.Filled.Search, contentDescription = “Search”, tint = Color.Gray, modifier = Modifier.size(iconSize.value).clickable { iconSize.value += 8.dp } ) Content Description: The contentDescription property of the Icon component provides a text description of the icon. This description is crucial for accessibility, allowing users with visual impairments to understand the purpose or meaning of the icon. It is recommended to provide a meaningful and concise description to ensure inclusive app experiences. Example: Icon with Content Description Icon( imageVector = Icons.Filled.Mic, contentDescription = “Microphone”, tint = Color.Blue, modifier = Modifier.size(36.dp) ) Modifier: The modifier property of the Icon component lets you apply additional styling or layout modifications to the icon. You can use modifiers such as padding, clickable, or align to adjust the positioning or interaction behaviour of the icon within its parent layout. Example: Icon with Modifier Icon( imageVector = Icons.Filled.Camera, contentDescription = “Camera”, tint = Color.Magenta, modifier = Modifier.size(48.dp).padding(8.dp).clickable { /* Handle click event */ } ) Conclusion: In this article, we explored the various properties of the Icon component in Jetpack Compose. By leveraging the tint property, you can apply custom colours to icons, seamlessly integrating them into your UI. Additionally, the size property allows for easy scaling of icons, ensuring a consistent and visually pleasing experience across different screen sizes. By utilizing the power of the Icon component and its properties, you can create stunning and user-friendly interfaces that elevate your Android applications to new heights. Remember, icons are not mere decorative elements; they serve as powerful visual cues that enhance the usability and aesthetics of your app. So, embrace the versatility of the Icon component in Jetpack Compose and let your imagination run wild as you design delightful user experiences. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

Icon in Compose Read More »

Image Composable in Jetpack Compose

Introduction Jetpack Compose is a toolkit for building Android user interfaces. One of its core components is the Image Composable, which provides a straightforward way to display images in an application. In this tutorial, we'll explore Image Composable and learn how to use it to display images in a Jetpack Compose project. Prerequisites To follow along with this tutorial, you'll need the following: Android Studio 4.0 or later. A basic understanding of Jetpack Compose. Getting Started First, create a new Jetpack Compose project in Android Studio. In the MainActivity.kt file, add the following code: import androidx.compose.foundation.Image import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp @Composable fun ImageComponent() { Image( painter = painterResource(R.drawable.image), contentDescription = null, modifier = Modifier .fillMaxWidth() .wrapContentSize() .height(200.dp), contentScale = ContentScale.Crop ) } This code defines an ImageComponent() a function that uses Image Composable to display an image. The Image Composable takes four parameters: painter: The image resource to display. contentDescription: A brief description of the image for accessibility purposes. modifier: Used to apply layout constraints and positioning to the image. contentScale: Defines how the image should be scaled to fit within its layout bounds. To display the image, we've used the painterResource() function to load the image resource, fillMaxWidth() to fill the entire width of the container, wrapContentSize() to wrap the image to its content size, and height() to set the image height to 200dp. We've also used ContentScale.Crop to crop the image to fit its bounds. Adding the Image to the UI To add the Image to the UI, modify the setContent() function in MainActivity.kt: setContent { Column( modifier = Modifier .fillMaxSize() .padding(16.dp) ) { Text(text = “Jetpack Compose Image Tutorial”) Spacer(modifier = Modifier.height(16.dp)) ImageComponent() } } In this code, we've added ImageComponent() to a Column Composable, which also includes a Text Composable with a title for the tutorial. We've also added a Spacer Composable to create some space between the title and the image Conclusion In this tutorial, we've explored the Image Composable in Jetpack Compose and learned how to use it to display images in an app. By following these steps, you'll easily incorporate images into your Jetpack Compose projects. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

Image Composable in Jetpack Compose Read More »

Box in Jetpack Compose

Box is a container in Jetpack Compose that can be used to wrap a single child element. It provides a way to group elements together and apply properties to them as a whole. Box also allows for easily adding padding, borders, and background color to a child element. Using Box in Jetpack Compose: To use Box in Jetpack Compose, first, we need to import the required libraries: import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp Once we have imported the required libraries, we can create a Box element by using the Box composable function. The Box function takes in a child element and a modifier as its parameters. Here is an example of using Box to create a rounded corner container with a background color and a padding of 16dp: @Composable fun RoundedBox() { Box( modifier = Modifier .padding(16.dp) .background(Color.Green, RoundedCornerShape(10.dp)) ) { // Child element goes here } } In the above example, we have used the Modifier.padding function to add a padding of 16dp to the Box element. We have also used the Modifier.background function to add a background color of green and a RoundedCornerShape with a radius of 10dp to the Box element. We can also use the Box function to create a circular container with a background color and a padding of 16dp: @Composable fun CircleBox() { Box( modifier = Modifier .padding(16.dp) .size(100.dp) .background(Color.Blue, CircleShape) ) { // Child element goes here } } In the above example, we have used the Modifier.size function to set the size of the Box element to 100dp x 100dp. We have also used the Modifier.background function to add a background color of blue and a CircleShape to the Box element. Conclusion: Box is a useful container in Jetpack Compose that allows for grouping elements together and applying properties to them as a whole. In this tutorial, we have explored how to use Box in Jetpack Compose and how to apply various properties to it. We hope that this tutorial has provided you with a better understanding of Box and how to use it in your own applications. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

Box in Jetpack Compose Read More »

Modifier in Jetpack Compose

The Modifier is a class in Jetpack Compose used to add behavior or modify the appearance of UI elements. It is similar to ViewGroup.LayoutParams in the traditional Android view system. The Modifier is a composable function that can be applied to any function, including layouts and widgets. Functions of Modifier in Jetpack Compose: Here are some of the tasks of the Modifier in Jetpack Compose: size(): The size function is used to specify the size of a composable element. For example, if you want to specify the height and width of a text element, you can use the size function. padding(): The padding function is used to add padding to a composable element. It takes four parameters that specify the padding for each side of the element. click(): The click function is used to add a click listener to a composable element. When the user clicks on the element, the click listener is triggered. background(): The background function is used to set the background color of a composable element. border(): The border function is used to add a border to a composable element. It takes two parameters that specify the color and width of the border. offset(): The offset function is used to offset a composable element from its original position. It takes two parameters that specify the x and y coordinates of the offset. fillMaxWidth(): The fillMaxWidth function is used to make a composable element fill the maximum width available. fillMaxHeight(): The fillMaxHeight function is used to make a composable element fill the maximum height available. Example Programs: Now, let's take a look at some example programs to see how the Modifier can be used in Jetpack Compose. Example program using the size() function: Text( text = “Hello, world!”, modifier = Modifier.size(100.dp) ) This program will create a text element with a size of 100dp x 100dp. Example program using the padding() function: Box( modifier = Modifier.padding(16.dp) ) { Text( text = “Hello, world!” ) } This program will create a box with a padding of 16dp on all sides and a text element inside the box. Example program using the click() function: Text( text = “Click me!”, modifier = Modifier.clickable(onClick = { /* Do something */ }) ) This program will create a text element that can be clicked. When the element is clicked, the onClick function is called. Example program using the background() function: Box( modifier = Modifier.background(Color.Blue) ) { Text( text = “Hello, world!” ) } This program will create a box with a blue background color and a text element inside the box. Conclusion: The Modifier is an essential component of Jetpack Compose that allows developers to modify the behavior and appearance of UI elements. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

Modifier in Jetpack Compose Read More »

Row and Columns in Jetpack Compose

Rows and columns are the basic building blocks of the Jetpack Compose UI. Rows are horizontal containers that hold one or more child elements, while columns are vertical containers that hold one or more child elements. Using rows and columns, you can arrange your UI elements in a grid-like structure. In Jetpack Compose, rows and columns are implemented using the Row and Column functions. These functions take a list of child elements as arguments and arrange them either horizontally (in the case of a Row) or vertically (in the case of a Column). Creating Rows in Jetpack Compose To create a row in Jetpack Compose, you can use the Row function. The Row function takes a list of child elements as an argument and arranges them horizontally. Here's an example of how to create a simple row with two text views: Row { Text(“First Text View”) Text(“Second Text View”) } In the above example, we've created a row with two text views. The Row function will automatically position the two text views side by side. If you want to add padding or spacing between the elements in the row, you can use the Modifier.padding or Modifier.spacing functions, respectively. For example: Row( Modifier.padding(16.dp) ) { Text(“First Text View”) Spacer(Modifier.width(16.dp)) Text(“Second Text View”) } In the above example, we've added padding to the row using the Modifier.padding function. We've also added spacing between the two text views using the Spacer function, which creates an empty space with a specified width. Creating Columns in Jetpack Compose Creating columns in Jetpack Compose is similar to creating rows. To create a column, you can use the Column function. The Column function takes a list of child elements as an argument and arranges them vertically. Here's an example of how to create a simple column with two text views: Column { Text(“First Text View”) Text(“Second Text View”) } In the above example, we've created a column with two text views. The Column function will automatically position the two text views on top of each other. If you want to add padding or spacing between the elements in the column, you can use the Modifier.padding or Modifier.spacing functions, respectively. For example: Column( Modifier.padding(16.dp) ) { Text(“First Text View”) Spacer(Modifier.height(16.dp)) Text(“Second Text View”) } In the above example, we've added padding to the column using the Modifier. padding function. We've also added spacing between the two text views using the Spacer function, which creates an empty space with a specified height. Conclusion In this tutorial, we've explored how to use rows and columns in Jetpack Compose to create a dynamic and flexible UI. Rows and columns are the basic building blocks of the Jetpack Compose UI and can be used to arrange UI elements in a grid-like structure. With Jetpack Compose, creating beautiful and responsive UI has never been easier. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

Row and Columns in Jetpack Compose Read More »

Text in Jetpack Compose

Text in Jetpack Compose is similar to TextView. The Text composable is used to show labels and paragraphs inside Android apps. This tutorial will show how to implement Text in the app and the available attributes of Text composable. Please check the following example program. The example program shows the implementation of the Text composable to display Hello World on the screen. It’s time to check out the attributes of Text Composable. Text Size: – The fontSize attribute is used to set the size of the text. Please note the fontSize attribute accepts size in TextUnit. So to recast a number into TextUnit use the .sp extension. Text Color: – The colour of the text can be specified using the colour attribute. This attribute accepts the object of the Color(androidx.compose.ui.graphics.Color) class. We can pass static variables of the Color class like Color.Black. Furthermore, we can also create the object of this class by passing the colour code in the constructor Color(0xFF000000). Font Weight: –  The font weight of the Text Composable can be mentioned using the fontWeight attribute. This attribute accepts the object of the FontWeight class. The FontWeight class has plenty of predefined font weights in the form of static variables.  Static Variable Thickness FontWight.Thin (FontWight.W100) Thin FontWight.ExtraLight (FontWight.W200)  ExtraLight FontWight.Light (FontWight.W300)  Light FontWight.Normal (FontWight.W400)  Normal FontWight.Medium (FontWight.W500)  Medium FontWight.SemiBold (FontWight.W600)  SemiBold FontWight.Bold (FontWight.W700) Bold FontWight.ExtraBold (FontWight.W800)  ExtraBold FontWight.Black (FontWight.W900)  Black Italic Text: – The fontStyle attribute makes text italic Text composable. Letter Spacing: – The space between letters can be updated using the letterSpacing attribute. This attribute accepts TextUnit. Woo hoo, we have done with some common characteristics of Text composable. There are numerous other attributes available. We recommend you play with Text Composable and observe what changes all other properties make. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

Text in Jetpack Compose Read More »

How to create a new Jetpack Compose

This tutorial will show how to create a new Jetpack compose project in Android Studio. Here Android Studio Dolphin | 2021.3.1 is being used for this tutorial. Please follow below mentioned steps to start with the first Jetpack Compose project. Open Android Studio. Click on File -> New -> New Project, But if you are opening Android Studio for the first time the Welcome to Android Studio screen will appear, There you can click on the New Project option. After clicking on New Project the following popup will appear. Click on the Empty Compose Activity option. A new popup will appear where you have to add the Name of the Project, the Package Name and location where you want to save the project, and the minimum android version. After this click on the finish button, This was the last step, let android studio do its Job and load all the required libraries and tools. When Android studio finishes loading, you can click the Run button to start the app in an emulator or on an actual device.  Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

How to create a new Jetpack Compose Read More »

What is Jetpack Compose

Jetpack Compose is a toolkit launched by Google to build native UI in Android. The main motive for launching this is to provide a productive and simple approach to creating UI in Android. Building UI using Compose is opposite to the traditional approach (building UI using XML). As we know, XML was an imperative UI design approach, but Jetpack compose is a declarative UI design approach. and it allows developers to design the UI based on what data they receive. There are several declarative UI frameworks like Flutter, React Native, SwiftUI and Jetpack Compose. In Jetpack Compose we describe UI by calling a series of functions and these functions convert data into UI hierarchy after setting up everything if data changes the framework automatically recalls the required function to update UI (This UI update process is known as recomposition). The amazing thing is that it allows developers to write logic and UI using a single language Kotlin.  Difference between Imperative and Declarative approaches: – Imperative: – In imperative, we create a separate prototype/model of the application’s UI. As you know in XML we create widgets and components rendered for users to see and interact with. This way of writing is more focused on the how rather than the what. Example Program: – Declarative: – This paradigm is more focused on what rather than how. It allows the user to create an entire application using a single programming language. Example Program: – In the above example programs you can see the difference between both approaches. In the Imperative approach we have created two different files to show “Hello World” on the screen, on the other hand in the Declarative approach we can achieve the same output by calling a single composable function Text(text = “Hello World”).  Benefits of using Jetpack compose: – Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

What is Jetpack Compose Read More »

About Jetpack Compose series

These days a new technology called Jetpack Compose is becoming popular among Android developers. Every Android developer talking about this and some of you might have already heard somewhere about Jetpack Compose. Now the question arises, what is this and how can it be helpful to us as Android developers? Jetpack Compose is a native UI toolkit launched by Google. The main motive to launch this is to provide a productive and simple approach to creating UI in Android. As you know, the best way to write UI in Android is by using XML. But how would you react if I mention that soon you are going to miss this old-school way of writing UI? Believe me, this is going to amaze you Jetpack Compose allows us to create UI by just using Kotlin, and this is going to be a game changer for us android developers In coming years there is a high chance that this new way of creating UI will replace traditional technologies. Because of this reason, it becomes very important to keep yourself up to date with industry standards. For your help, we are going to create a detailed series about Jetpack Compose. Which will help you to understand every single topic about Compose. After finishing this series, you will be able to start a Jetpack Compose project from scratch and finish it like a pro. What is the agenda of the series: – The main agenda of this series is to provide knowledge to its readers about the following Pre-define composable (Buttons, Text, Radio, Checkbox, etc) Use of state  How to create custom composable  Animate composable  Creating custom UI using Canvas (Pie chart, Gauge, etc) Prerequisites to start this series: – This series is all about Jetpack Compose. So we will not cover any basic Android app development topic. So please make sure before starting that you have done with the following Prerequisite.  Knowledge of Android app development. Knowledge of Kotlin syntax and features (lambda, annotations, list functions, etc). Knowledge about reactive programming (LiveData, Flow, etc). Knowledge of some design patterns such as MVC, MVP, and MVVM. Parvesh SandilaParvesh Sandila is a passionate web and Mobile app developer from Jalandhar, Punjab, who has over six years of experience. Holding a Master’s degree in Computer Applications (2017), he has also mentored over 100 students in coding. In 2019, Parvesh founded Owlbuddy.com, a platform that provides free, high-quality programming tutorials in languages like Java, Python, Kotlin, PHP, and Android. His mission is to make tech education accessible to all aspiring developers.​ new.owlbuddy.com

About Jetpack Compose series Read More »

Scroll to Top
×