# Stories by Ban Markovic on Medium

Stories by Ban Markovic on Medium

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Jetpack Compose Clip or Cut a Composable with Custom Image Shape

DevFeed: [Jetpack Compose Clip or Cut a Composable with Custom Image Shape](<https://devfeed.tech/articles/jetpack-compose-clip-or-cut-a-composable-with-custom-image-shape-25850.md>)

Original publisher: [Read original article](<https://medium.com/@banmarkovic/jetpack-compose-clip-or-cut-a-composable-with-custom-image-shape-062dde54d4b2?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2024-02-14T17:25:40Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Graphics](<https://devfeed.tech/topics/graphics.md>)

Tags: [alignment](<https://devfeed.tech/tags/alignment.md>), [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [building](<https://devfeed.tech/tags/building.md>), [component](<https://devfeed.tech/tags/component.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-ui](<https://devfeed.tech/tags/compose-ui.md>), [customization](<https://devfeed.tech/tags/customization.md>), [extend](<https://devfeed.tech/tags/extend.md>), [images](<https://devfeed.tech/tags/images.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [layout](<https://devfeed.tech/tags/layout.md>), [merge](<https://devfeed.tech/tags/merge.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

A tutorial showing how to clip a Jetpack Compose composable to a custom image shape. It builds a health-bar example, then uses PorterDuff operators and Modifier.drawWithContent to combine the image shape with colored content.

### Source excerpt

As an Android developer, I face all sorts of challenges provided to me by my fellow designers. One of them was actually building an UI component that has a custom shape in a form of an image. This was required because we wanted to display a special type of a progress bar by fulfilling the image shape with gradient. Because I didn't find this functionality trivial to implement, I decided to show how I solved this issue with some fun example. Example Here is a simple game where I utilized cutting of my composable. The game consists of one plane with full health. Upon each hit, it looses 10% of its health. Game is over once the plane remains with no health. Game Setup First, let me show you how I formed the basic layout for this game. It will contain the gray square and Hit button. Column( modifier = Modifier.fillMaxSize().background(Color.Black), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Box( modifier = Modifier .size(240.dp) .background(Color.LightGray) ) Spacer(modifier = Modifier.height(40.dp)) Button( onClick = { /* TODO */ } ) { Text("HIT") } } Next step, is to create custom Composable called SquareHealth. SquareHealth is expecting the progress value (from 0.0 to 1.0). This will determine the height of the green area inside my gray square (aligned at bottom). It will represent remaining health for my Square. @Composable fun SquareHealth(healthPercentage: Float) { Box( modifier = Modifier .size(240.dp) .background(Color.LightGray) ) { Box( modifier = Modifier .fillMaxWidth() .height((240 * healthPercentage).dp) .background(Color.Green) .align(Alignment.BottomCenter) ) } } Now, I can call it instead of the static gray Box inside my screen. The basic layout is now set, and I just need to set initial health progress to 1.0, and enable my button to decrease the health percentage by 0.1 on each click. var healthPercentage by remember { mutableStateOf(1.0f) } Column( modifier = Modifier .fillMaxSize() .background(Co

## Essential Components of an Android Developer GitHub Showcase Project

DevFeed: [Essential Components of an Android Developer GitHub Showcase Project](<https://devfeed.tech/articles/what-every-android-developer-should-have-in-their-github-25844.md>)

Original publisher: [Read original article](<https://blog.stackademic.com/what-every-android-developer-should-have-in-their-github-de8deab051b9?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2024-02-05T11:00:04Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [REST API](<https://devfeed.tech/topics/rest-api.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [github](<https://devfeed.tech/tags/github.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [mvi](<https://devfeed.tech/tags/mvi.md>), [mvvm](<https://devfeed.tech/tags/mvvm.md>), [portfolio](<https://devfeed.tech/tags/portfolio.md>), [rest-api](<https://devfeed.tech/tags/rest-api.md>), [screen](<https://devfeed.tech/tags/screen.md>), [unit-tests](<https://devfeed.tech/tags/unit-tests.md>)

### AI overview

The article recommends building a concise Android showcase project for a GitHub portfolio. The project should use two screens to fetch and display a list from a REST API, support navigation to item details, demonstrate MVI or MVVM architecture, organize files clearly, handle asynchronous work, include unit tests, and use dependency injection.

### Source excerpt

In the competitive world of Android development, having a strong GitHub portfolio is crucial for showcasing your skills to potential employers. One effective way to demonstrate your expertise is by creating a concise yet comprehensive project that highlights key aspects of Android development. In this article, we'll explore the essential components that every Android developer should have in their GitHub, focusing on a project that encapsulates fundamental skills. The Project Overview A successful showcase project should include two screens and cover the following key functionalities: Fetching and Displaying Data - Utilize a REST API to fetch a list of items. - Display this list on the first screen of the app. Navigation and Detailed Information - Enable users to navigate to a second screen by clicking on a specific item. - On the second screen, display more detailed information about the selected item. Key Considerations for the Showcase ProjectArchitecture -- MVI or MVVM Clearly implement and showcase your understanding of the chosen architecture (MVI or MVVM). Organize code files in a logical and easily understandable structure. File Organization Demonstrate a well-organized project structure, separating concerns and making codebase easily maintainable (feature-based or type-based folders structure). Asynchronous Communication Showcase your proficiency in handling asynchronous tasks by using an appropriate library (e.g., Kotlin Coroutines, LiveData, RxJava). Unit Tests Impress potential employers by including unit tests to validate the functionality of critical components (cover your ViewModel, UseCase, Repository classes with unit tests). Dependency Injection (DI): Implement and demonstrate your use of dependency injection for managing component dependencies (Hilt, Dagger, Koin). Why This Project Matters This concise project effectively showcases your abilities in: Displaying a list of items Fetching data from the internet Implementing navigation between screens

## Get current flavor in Android Gradle

DevFeed: [Get current flavor in Android Gradle](<https://devfeed.tech/articles/get-current-flavor-in-android-gradle-25847.md>)

Original publisher: [Read original article](<https://medium.com/@banmarkovic/get-current-flavor-in-android-gradle-6d23d27259e3?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2023-08-07T12:20:20Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Gradle](<https://devfeed.tech/topics/gradle.md>), [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [configuration](<https://devfeed.tech/topics/configuration.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [apk](<https://devfeed.tech/tags/apk.md>), [assemble](<https://devfeed.tech/tags/assemble.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [groovy](<https://devfeed.tech/tags/groovy.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [programming](<https://devfeed.tech/tags/programming.md>)

### AI overview

This tutorial explains how Android product flavors support multiple app variants from one codebase and how to identify the selected flavor in Gradle scripts. It focuses on a Kotlin DSL implementation of a getCurrentFlavor function and mentions a Groovy version.

### Source excerpt

Gradle is a topic that most Android developers postpone to learn as much as they can. This happens until we realize that it is a crucial part when it comes to packaging our apps or SDKs (here is my article that can help you out with understanding Gradle better). Since the diversity of Android devices is huge, we always need to strive not to package unnecessary things. Product flavors Sometimes it is required from us to publish different versions of our app, depending on the different requirements of our clients. This leads us to having one codebase that can support multiple configuration changes (enabling or disabling particular features) depending on our clients. To avoid changing our code each time we want to publish a different version of our app, we use product flavors. They enable us to set up different app variants at project level, and then we can reference them in our code, in order to enable or disable something. Problem Enabling or disabling particular features inside our Kotlin code is not that complex, but in order to follow those toggles, sometimes we would also like to include or exclude some plugins or libraries. Since this type of work is done in Gradle, there is a need for us to know which product flavor is selected in our Gradle file. Solution Writing Gradle scripts can be done with Kotlin DSL or Groovy, and since we already know Kotlin, I will focus on explaining the Kotlin DSL solution and later on I will also provide the full Groovy version of our getCurrentFlavor function. By using Kotlin DSL in our Gradle scripts, we can add any function at the bottom of our app/build.gradle.kts file, so let's create our getCurrentFlavor() function that returns an empty String. fun getCurrentFlavor(): String { return "" } Since we are inside our build.gradle.kts file, we have a reference to a Gradle object that belongs to our project. Inside it, we have the information of the parameters that the Gradle object uses for starting the build. By having that informa

## Which Cross-platform Framework to Choose For Building Startup as an Android Developer

DevFeed: [Which Cross-platform Framework to Choose For Building Startup as an Android Developer](<https://devfeed.tech/articles/which-cross-platform-framework-to-choose-for-building-startup-as-an-android-developer-25845.md>)

Original publisher: [Read original article](<https://blog.startupstash.com/which-cross-platform-framework-to-choose-for-building-startup-as-an-android-developer-45488d68a4d?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2023-05-02T09:34:59Z

Content type: opinion

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [cross-platform](<https://devfeed.tech/topics/cross-platform.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [Flutter](<https://devfeed.tech/topics/flutter.md>), [React Native](<https://devfeed.tech/topics/react-native.md>), [Java](<https://devfeed.tech/topics/java.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [app-development](<https://devfeed.tech/tags/app-development.md>), [cross-platform](<https://devfeed.tech/tags/cross-platform.md>), [developer](<https://devfeed.tech/tags/developer.md>), [flutter](<https://devfeed.tech/tags/flutter.md>), [framework](<https://devfeed.tech/tags/framework.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [programming](<https://devfeed.tech/tags/programming.md>), [react-native](<https://devfeed.tech/tags/react-native.md>), [startup](<https://devfeed.tech/tags/startup.md>)

### AI overview

An Android developer describes choosing a cross-platform framework for a mobile application intended to support both iOS and Android. The article compares personal experiences with React Native and Flutter and introduces Kotlin Multiplatform as another approach, while acknowledging limited experience with the frameworks.

### Source excerpt

I've been working as an Android developer for more than five years, and it is definitely an interesting job. Specializing in one field enables you to have a great career, as long as you are willing to improve day by day. Even though I like the path I've taken in my career, there is always one small voice in the back of my head that bugs me. It always reminds me that my skills are quite limited when working on some personal ideas. No business is focused solely on Android applications. There are some businesses that support only the iOS platform, but in most cases, it is expected of you to support both iOS and Android. Personal project For some time now, I had an idea regarding a mobile application that could help users in their self-improvement journey. I built the team necessary for developing it. We clarified the features we wanted to build and designed the actual MVP. Next step: development. Choosing cross-platform framework Since I'm the only one in the team that has experience in developing mobile apps, it is my duty to develop mobile apps for iOS and Android. I've experimented on my own with React Native and Flutter for a few practice projects over the past couple years. I can't say I spent a lot of time on them, but I did form some opinions. React Native was something that didn't click for me. Everything looked so messy, probably because I'm used to object-oriented programming approach and here I was using Javascript. I'm aware of Typescript, however several libraries are written in Javascript, thus I had to use a lot of undefined type "any" when interacting with them in Typescript. This felt really dirty to me, since I'm coming from the Java and Kotlin environment. Also, I'm not a big fan of CSS. Flutter was something that I enjoyed playing with. Especially for the first time I experimented with Dart. It seemed like a great improvement compared to the Java Android project. Later on, when I switched to Kotlin, I saw that even though Dart seemed better than Jav

## What is Gradle and why do we use it as Android developers?

DevFeed: [What is Gradle and why do we use it as Android developers?](<https://devfeed.tech/articles/what-is-gradle-and-why-do-we-use-it-as-android-developers-25852.md>)

Original publisher: [Read original article](<https://medium.com/@banmarkovic/what-is-gradle-and-why-do-we-use-it-as-android-developers-572a07b3675d?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2023-01-16T12:52:02Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Gradle](<https://devfeed.tech/topics/gradle.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [android-apps](<https://devfeed.tech/topics/android-apps.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [Library](<https://devfeed.tech/topics/library.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [automation-tools](<https://devfeed.tech/tags/automation-tools.md>), [bytecode](<https://devfeed.tech/tags/bytecode.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [groovy](<https://devfeed.tech/tags/groovy.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [libraries](<https://devfeed.tech/tags/libraries.md>)

### AI overview

A tutorial explaining Gradle's role in Android development, including how build.gradle files specify dependencies and how Gradle automates application building and running.

### Source excerpt

At the start of a journey for an Android developer, no one pays attention to Gradle. We are mostly focused on writing Kotlin code and developing Android apps that bring great value to our customers and look as beautiful as possible. When building them, sometimes we stumble upon a problem that is already solved by someone else on the internet and they were kind enough to share their project in a form of library, that we are able to implement in our app, and customize it to our needs. To be able to do so, we are using build.gradle file for implementing those libraries that help us build our apps, by specifying their unique package names and versions. This is probably the most common use case of our Gradle usage inside our Android projects. Motivation At the beginning of my career I didn't see a need for better understanding of Gradle, because for me it represented only the place where I wrote the names of the libraries I wanted to use inside my project. With that kind of approach, I didn't have any knowledge regarding it, and I was scared to change anything inside those files, because I was afraid I would break everything. After some time I realized that gradle files are built with code.. And I am a programmer.. So why am I avoiding it when I can learn it like any other programming language. What an epiphany, right? That's why I decided to write an article regarding the gradle files inside Android project. Just so anyone can read and understand them. Gradle Gradle is a build tool that we use for Android development to automate the process of building and publishing apps. Now, you may think that building and running the application is quite easy; we can just press Run button in Android Studio. Well, that just triggers Gradle's built-in tasks (functions) that are responsible for running the application on our emulator or real device. This process requires a couple of steps to be successfully completed in order for us to see the running app. These are the general steps t

## Jetpack Compose clear back stack, popBackStack inclusive explained

DevFeed: [Jetpack Compose clear back stack, popBackStack inclusive explained](<https://devfeed.tech/articles/jetpack-compose-clear-back-stack-popbackstack-inclusive-explained-25849.md>)

Original publisher: [Read original article](<https://medium.com/@banmarkovic/jetpack-compose-clear-back-stack-popbackstack-inclusive-explained-14ee73a29df5?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2023-01-03T10:31:50Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [navigation](<https://devfeed.tech/topics/navigation.md>), [Android](<https://devfeed.tech/topics/android.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [compose](<https://devfeed.tech/tags/compose.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [route](<https://devfeed.tech/tags/route.md>), [screen](<https://devfeed.tech/tags/screen.md>), [state](<https://devfeed.tech/tags/state.md>)

### AI overview

A tutorial on managing navigation back stacks in Android apps built with Jetpack Compose. It explains opening screens with NavHostController.navigate, closing the current screen with popBackStack, and closing multiple screens using a destination route and the inclusive boolean parameter.

### Source excerpt

Jetpack Compose clear back stack, popUpTo/popBackStack inclusive explained Building the navigation for our Android app that is built with Jetpack Compose requires usage of navigation-compose library that is provided by Android team. In order to master closing the screens and tracking our back stack state, it is important to understand the stack data structure that is used for this purpose. Before we can close multiple screens, we need to open them. That's why I decided to separate this article into three sections that represent the most common ways used when navigating through apps: Opening a new screen, Closing current screen, Closing multiple screens at once. Open new screen Navigating from one to another screen is pretty straightforward using navigation-compose lib, we can just use NavHostController and call navigate(...) function with the route as parameter. This will lead into creating a new screen, that is going to be placed on top of our current screen. Example Let's say we have our Login screen opened, and after successful email and password input, we want to load Home screen, our stack would look like this. Close current screen Apart from navigating to a new screen, closing the currently opened one is also a pretty common action in navigation. To achieve this, we can use popBackStack() function from our NavHostController. As the name of the function suggests, it will take the top screen from the stack, and it will remove it. Example Removing our Home screen by calling the popBackStack function will make our stack look like this. Close multiple screens The past two examples were pretty simple, but I wanted to make sure that we understand how navigation-compose lib is storing the data regarding the order of our opened screens. When it comes to closing multiple screens, we can actually use an already known function, popBackStack, but we will need to pass two parameters: route -- represents the destination (screen) that already exists in our stack, and it will ena

## Jetpack Compose OTP input field

DevFeed: [Jetpack Compose OTP input field](<https://devfeed.tech/articles/jetpack-compose-otp-input-field-25853.md>)

Original publisher: [Read original article](<https://proandroiddev.com/jetpack-compose-otp-input-field-bcfa22c85e5f?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2022-12-19T14:51:05Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [Android](<https://devfeed.tech/topics/android.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Code](<https://devfeed.tech/topics/code.md>), [Development](<https://devfeed.tech/topics/development.md>), [Authentication](<https://devfeed.tech/topics/authentication.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Material Design](<https://devfeed.tech/topics/material-design.md>), [passwords](<https://devfeed.tech/topics/passwords.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [authentication](<https://devfeed.tech/tags/authentication.md>), [code](<https://devfeed.tech/tags/code.md>), [component](<https://devfeed.tech/tags/component.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-ui](<https://devfeed.tech/tags/compose-ui.md>), [development](<https://devfeed.tech/tags/development.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [material-design](<https://devfeed.tech/tags/material-design.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [mobile-apps](<https://devfeed.tech/tags/mobile-apps.md>), [otp](<https://devfeed.tech/tags/otp.md>), [password](<https://devfeed.tech/tags/password.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

A tutorial on building a customizable one-time password input field for Android with Jetpack Compose and BasicTextField. It explains why BasicTextField can be preferable to Material TextField for customization, configures a numeric password keyboard, and limits input to six digits.

### Source excerpt

One-time password (OTP), also called dynamic password, one-time PIN, and one-time authorization code (OTAC), is password that is only valid for one login session. Most commonly, it is received in a format of 4 or 6 digit code, through SMS, and it used for implementation of two-factor authentication. Implementing OTP support inside our mobile apps requires us to build a custom UI input field, which should be strictly customized for handling the received OTP code. Motivation Since Jetpack Compose is a new UI toolkit for Android development, I wanted to write an article regarding how we can make our own custom OTP input field using BasicTextField. Custom OTP input Creating input fields with Compose UI is quite simple. There is already an existing Material component called TextField, that we can use. It has a lot of built-in functionalities because it follows Material design principles. That also comes with some drawbacks, for example, if we wanted to customize our input field, we would have struggled to do so with TextField, because it isn't as flexible. That's why we need another component that is a bit lower-level compared to TextField, but it enables us to customize it the way that suits us the best. I'm talking about BasicTextField. Implementation Firstly, lets implement a simple BasicTextField that enables it to open a keyboard with only numbers. We can do that by setting up the keybaordOptions parameter with keyboardType set to NumberPassword. If you've wondered why we use NumberPassword and not just Number, it is because the keyboard that is opened for the Number keyboard type contains dot, comma and dash characters, and we don't need anything other than digits inside our OTP input field. Next step we need to do is to implement more restrictions inside our input field. In case we know that our OTP must be a 6 digit code, our input field should be able to receive max 6 digits, and not allow user to input more than that. To accomplish max characters restriction, w

## Jetpack Compose under the hood

DevFeed: [Jetpack Compose under the hood](<https://devfeed.tech/articles/jetpack-compose-under-the-hood-25851.md>)

Original publisher: [Read original article](<https://medium.com/@banmarkovic/jetpack-compose-under-the-hood-7bb88f08c47e?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2022-12-12T10:49:33Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Android](<https://devfeed.tech/topics/android.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [SDK](<https://devfeed.tech/topics/sdk.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-apps](<https://devfeed.tech/tags/android-apps.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [compose](<https://devfeed.tech/tags/compose.md>), [deprecated](<https://devfeed.tech/tags/deprecated.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [sdk](<https://devfeed.tech/tags/sdk.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This tutorial introduces Jetpack Compose by comparing it with Android's traditional View System. It explains how Android UI development evolved from findViewById and Butter Knife to Kotlin synthetics, ViewBinding, and DataBinding, and frames Compose as a response to increasing UI complexity and UX requirements.

### Source excerpt

The development of Android mobile apps is nothing new. We have been doing it since 2009, when the Android SDK was published. In the meantime, many APIs used for developing Android mobile apps were updated, but the general idea of app development remained. Looking at something as basic as accessing the UI elements and modifying them, we can see the constant need for improvement and change. We've started with findViewById, then we transferred to Butter Knife library. After we switched from Java to Kotlin, we were introduced to Kotlin synthetics, then it went deprecated soon enough, and it was replaced by ViewBinding. In the meantime, we also received a new support library, DataBinding, that enabled us to bind our UI components to data sources from our app. As we can see, even though the final goal was the same (accessing UI elements defined inside XML and modifying their values), the APIs for reaching our goal were changed quite drastically and quite often. Why so many changes? The constant need for polishing the UX of ours apps introduced a lot more complexity in our mobile app projects. Designers demand more and more from their developers, and developers constantly strive for making their code as flexible and reusable as possible. This is something that gets harder and harder to accomplish when your base is not particularly designed for handling new types of designers requirements. Motivation To better learn something new, we need to understand the differences between what we know (Android View System) and the new things that are introduced by the new system (Jetpack Compose). Sometimes this feels overwhelming, because at the beginning, most of it looks like magic as we don't know anything about it. By familiarizing ourselves with Jetpack Compose way of working, we are putting ourselves in a better position to utilize this new tool. Android View System The base for developing Android apps most of us are currently using is Android View System. It is here since 2009 a

## Jetpack Compose Bottom Border

DevFeed: [Jetpack Compose Bottom Border](<https://devfeed.tech/articles/jetpack-compose-bottom-border-25848.md>)

Original publisher: [Read original article](<https://medium.com/@banmarkovic/jetpack-compose-bottom-border-8f1662c2aa84?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2022-11-14T10:36:16Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Canvas](<https://devfeed.tech/topics/canvas.md>), [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [article](<https://devfeed.tech/tags/article.md>), [canvas](<https://devfeed.tech/tags/canvas.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [jetpack-compose-tutorial](<https://devfeed.tech/tags/jetpack-compose-tutorial.md>)

### AI overview

A tutorial showing how to draw a bottom border on a Jetpack Compose UI component using Canvas, Modifier.drawBehind, DrawScope, and drawLine. It explains the coordinate system and converting dp stroke width to pixels.

### Source excerpt

Android Jetpack Compose provides us API for drawing borders on any UI component, and it couldn't be any easier. But, drawing single edge borders isn't supported yet, by default. Goal This article will show you a custom way of drawing bottom borders step by step using Canvas. Hopefully at the end of it, you will learn not only how to draw a bottom border, but you will be able to use that knowledge to draw any border on any side (top, bottom, left, right) you want. Solution Drawing something on the screen basically leads to accessing the canvas and telling it where to draw which pixel. Luckily for us, Jetpack Compose's Modifier element comes with the method drawBehind, that provides us access to the canvas behind given UI element with a lot of drawing options through DrawScope. drawBehind -- Draw into a Canvas behind the modified content. DrawScope -- Creates a scoped drawing environment with the provided Canvas. The DrawScope has a lot of helper methods for drawing onto our canvas. In our case, we want to draw the bottom border, which is basically the simple line that is placed at the bottom of our UI component. By having access to the DrawScope and its Canvas, we can use DrawScope's helper function drawLine to draw our bottom border. drawLine To draw any line, there are a couple of parameters we need to define: color, width, start point, end point. In this example, we will draw a red line with the width of 4 dp (but you can change this to your liking, sky is the limit). The only step that is missing for drawing our bottom border is defining our start and end point. Let's first look at our Text UI component to have a better understanding of the canvas that we are working with. In this example, our canvas is basically everything that is gray, and the bottom of it we want to draw a line. Canvas is represented with a coordinate system, so every point is defined by two values x and y. Top-left corner of our UI component's canvas, is represented with (0, 0). Bottom-right co

## AutoSize TextField in Android Jetpack Compose

DevFeed: [AutoSize TextField in Android Jetpack Compose](<https://devfeed.tech/articles/autosize-textfield-in-android-jetpack-compose-25846.md>)

Original publisher: [Read original article](<https://medium.com/@banmarkovic/autosize-textfield-in-android-jetpack-compose-7d2a601636f5?source=rss-8aced922ece------2>)

Author: Ban Markovic

Published: 2022-08-08T08:55:06Z

Content type: tutorial

Language: en

Sources: [Stories by Ban Markovic on Medium](<https://devfeed.tech/sources/stories-by-ban-markovic-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [XML](<https://devfeed.tech/topics/xml.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-jetpack](<https://devfeed.tech/tags/android-jetpack.md>), [compose-ui](<https://devfeed.tech/tags/compose-ui.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This tutorial explains how to implement an autosizing TextField in Android Jetpack Compose. It calculates the input field's available width, measures text using ParagraphIntrinsics, and decreases the font size until the text fits within the field while accounting for default horizontal padding.

### Source excerpt

By introducing Jetpack Compose UI framework, Android has made huge improvement towards speeding up the process of developing Android apps. The only drawback at the moment is that the framework is still young, therefore quite a few features are lacking when compared to the previous View system (XML). One of the latest struggles I had with Jetpack Compose was the implementation of the input field that resizes its font when the text is wider than the input field. Autosizing input field In this post, I'm going to cover steps necessary for the implementation of mentioned TextField in JetpackCompose. In case you are impatient and you want to check Github repo immediately, here is the link with working example. What are we trying to accomplish here Every time our text exceeds the width of our TextField box, we must calculate the new font size to make our content fit within the boundaries of the TextField box. Solution For this specific purpose, we will leverage a few of the features that Jetpack Compose has made available. But first, let's break this work down into three smaller ones so that we can tackle them one at a time: calculate the max width of the input field, calculate the width of the text with given font size, decrease the font size until the width of the given text fits the max width of the input field. 1. Max width of the input field Since working solely with TextField won't give us the information about its width, we are going to use one of the Jetpack Compose composables called BoxWithConstraints, as a parent of our TextField. It can help us get the maxWidth info. BoxWithConstraints(modifier = modifier.fillMaxWidth()) { val textFieldDefaultHorPad = 16.dp val maxInputWidth = maxWidth - 2 * textFieldDefaultHorPad TextField(...) } Here, it's important to note that TextField contains default horizontal padding that is 16 dp on each side, that's why we are calculating our maxInputWidth by subtracting two paddings from BoxWithConstraints maxWidth. If we didn't sub