• Stars
    star
    322
  • Rank 130,398 (Top 3 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created over 2 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

πŸš€πŸžπŸ’ͺ Collection of Images, Modifiers, utility functions for Jetpack Compose to expand and enrich displaying, manipulating, scaling, resizing, zooming, and getting cropped ImageBitmap based on selection area

Compose Image on Steroids

Collection of Images, Modifiers, utility functions for Jetpack Compose to expand and enrich displaying, manipulating, scaling, resizing, zooming, and getting cropped ImageBitmap based on selection area, before/after image to with handle to show partial of both images and more is cooking up

intro_image.mp4
zoom.mp4

Gradle Setup

To get a Git project into your build:

  • Step 1. Add the JitPack repository to your build file Add it in your root build.gradle at the end of repositories:
allprojects {
  repositories {
      ...
      maven { url 'https://jitpack.io' }
  }
}
  • Step 2. Add the dependency
dependencies {
    implementation 'com.github.SmartToolFactory:Compose-Image:<version>'
}

Image

ImageWithConstraints

A composable that lays out and draws a given ImageBitmap. This will attempt to
size the composable according to the ImageBitmap's given width and height.

ImageScope returns constraints, width and height of the drawing area based on contentScale and rectangle of imageBitmap drawn. When a bitmap is displayed scaled to fit area of Composable space used for drawing image is represented with ImageScope.imageWidth and ImageScope.imageHeight. When we display a bitmap 1000x1000px with ContentScale.Crop if it's cropped to 500x500px ImageScope.rect returns IntRect(250,250,750,750).

This composable enables building other Image based Composables that require you to know spaces around ImageBitmap based on ContentScale or which section of Bitmap is drawn to Canvas

@Composable
fun ImageWithConstraints(
    modifier: Modifier = Modifier,
    imageBitmap: ImageBitmap,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    contentDescription: String? = null,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null,
    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
    drawImage: Boolean = true,
    content: @Composable ImageScope.() -> Unit = {}
) {
    imageScope: ImageScope->

}

returns ImageScope which is

@Stable
interface ImageScope {
    /**
     * The constraints given by the parent layout in pixels.
     *
     * Use [minWidth], [maxWidth], [minHeight] or [maxHeight] if you need value in [Dp].
     */
    val constraints: Constraints

    /**
     * The minimum width in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val minWidth: Dp

    /**
     * The maximum width in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val maxWidth: Dp

    /**
     * The minimum height in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val minHeight: Dp

    /**
     * The maximum height in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val maxHeight: Dp

    /**
     * Width of area inside BoxWithConstraints that is scaled based on [ContentScale]
     * This is width of the [Canvas] draws [ImageBitmap]
     */
    val imageWidth: Dp

    /**
     * Height of area inside BoxWithConstraints that is scaled based on [ContentScale]
     * This is height of the [Canvas] draws [ImageBitmap]
     */
    val imageHeight: Dp

    /**
     * [IntRect] that covers boundaries of [ImageBitmap]
     */
    val rect: IntRect
}
  • drawImage param is to set whether this Composable should draw on Canvas. ImageWithConstraints can be used not only for drawing but providing required info for its content or child Composables so child can draw ImageBitmap as required by developer.

ImageWithThumbnail

ImageWithThumbnail displays thumbnail of bitmap it draws in corner specified by ThumbnailState.position. When touch position is close to thumbnail position if ThumbnailState.dynamicPosition is set to true moves thumbnail to corner specified by ThumbnailState.moveTo

@Composable
fun ImageWithThumbnail(
    modifier: Modifier = Modifier,
    imageBitmap: ImageBitmap,
    contentScale: ContentScale = ContentScale.Fit,
    alignment: Alignment = Alignment.Center,
    contentDescription: String?,
    thumbnailState: ThumbnailState = rememberThumbnailState(),
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null,
    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
    drawOriginalImage: Boolean = true,
    onDown: ((Offset) -> Unit)? = null,
    onMove: ((Offset) -> Unit)? = null,
    onUp: (() -> Unit)? = null,
    onThumbnailCenterChange: ((Offset) -> Unit)? = null,
    content: @Composable ImageScope.() -> Unit = {}
) {

}

Transform

These Composables and Modifiers are for scaling or resizing Image or Composable and move from current position using handles.

TransformLayout

Composable that changes scale of its content with handles, translates its position when dragged inside bounds.

@Composable
fun TransformLayout(
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    handleRadius: Dp = 15.dp,
    handlePlacement: HandlePlacement = HandlePlacement.Corner,
    onDown: (Transform) -> Unit = {},
    onMove: (Transform) -> Unit = {},
    onUp: (Transform) -> Unit = {},
    content: @Composable () -> Unit
) {

}

MorphLayout

Composable that changes dimensions of its content with handles, translates its position when dragged inside bounds.

⚠️ Be careful about maximum dimension can be assigned to this Composable with handles because maximum width and height depends on how a Composable, Column for instance, lays out its children. It can be expanded up to remaining space if other siblings occupy rest of the parent's available space set with parent Layout

@Composable
fun MorphLayout(
    modifier: Modifier = Modifier,
    containerModifier: Modifier = Modifier,
    enabled: Boolean = true,
    handleRadius: Dp = 15.dp,
    handlePlacement: HandlePlacement = HandlePlacement.Corner,
    updatePhysicalSize: Boolean = false,
    onDown: () -> Unit = {},
    onMove: (DpSize) -> Unit = {},
    onUp: () -> Unit = {},
    content: @Composable () -> Unit
) {
}

Zoom

Zoom feature provides zooming in or out Image, or Composables with animations and getting data about current transform or image Using Callbacks.

Modifier.zoom()

Modifier that zooms, pans, and rotates any Composable it set to. when [clip] is true Modifier.clipToBounds() is used to limit content inside Composable bounds consume param is for Modifier.pointerInput to consume current events to prevent other gestures like scroll, drag or transform to initiate. Callbacks notify user that gesture has started, going on finished with [ZoomData] that contains current transformation information

fun Modifier.zoom(
    key: Any? = Unit,
    consume: Boolean = true,
    clip: Boolean = true,
    zoomState: ZoomState,
    onGestureStart: ((ZoomData) -> Unit)? = null,
    onGesture: ((ZoomData) -> Unit)? = null,
    onGestureEnd: ((ZoomData) -> Unit)? = null
)

Parameters

  • key/key1-key2/keys are used for restarting Modifier.pointerInput(*keys) and remember for getting ZoomState
  • consume flag to prevent other gestures such as scroll, drag or transform to get
  • clip when set to true clips to parent bounds. Anything outside parent bounds is not drawn empty space on sides or edges of parent.
  • zoomState State of the zoom that contains option to set initial, min, max zoom, enabling rotation, pan or zoom and contains current [ZoomData]event propagations
  • onGestureStart callback to to notify gesture has started and return current ZoomData of this modifier
  • onGesture callback to notify about ongoing gesture and return current ZoomData of this modifier
  • onGestureEnd callback to notify that gesture finished and return current ZoomData of this modifier

ZoomState

Create and [remember] the [ZoomState] based on the currently appropriate transform configuration to allow changing pan, zoom, and rotation.

@Composable
fun rememberZoomState(
    initialZoom: Float = 1f,
    initialRotation: Float = 0f,
    minZoom: Float = 1f,
    maxZoom: Float = 5f,
    zoomable: Boolean = true,
    pannable: Boolean = true,
    rotatable: Boolean = false,
    limitPan: Boolean = false,
    key1: Any? = Unit
): ZoomState {
    return remember(key1) {
        ZoomState(
            initialZoom = initialZoom,
            initialRotation = initialRotation,
            minZoom = minZoom,
            maxZoom = maxZoom,
            zoomable = zoomable,
            pannable = pannable,
            rotatable = rotatable,
            limitPan = limitPan
        )
    }
}

Parameters

  • initialZoom zoom set initially
  • initialRotation rotation set initially
  • minZoom minimum zoom value
  • maxZoom maximum zoom value
  • limitPan limits pan to bounds of parent Composable. Using this flag prevents creating empty space on sides or edges of parent
  • zoomable when set to true zoom is enabled
  • pannable when set to true pan is enabled
  • rotatable when set to true rotation is enabled

ZoomableImage

Zoomable image that zooms in and out in [ [minZoom], [maxZoom] ] interval and translates zoomed image based on pointer position. Double tap gestures reset image translation and zoom to default values with animation. Callbacks notify user that gesture has started, going on finished with [ZoomData] that contains current transformation information

@Composable
fun ZoomableImage(
    modifier: Modifier = Modifier,
    imageBitmap: ImageBitmap,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    contentDescription: String? = null,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null,
    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
    initialZoom: Float = 1f,
    minZoom: Float = 1f,
    maxZoom: Float = 5f,
    limitPan: Boolean = true,
    zoomable: Boolean = true,
    pannable: Boolean = true,
    rotatable: Boolean = false,
    clip: Boolean = true,
    clipTransformToContentScale: Boolean = false,
    consume: Boolean = true,
    onGestureStart: (ZoomData) -> Unit = {},
    onGesture: (ZoomData) -> Unit = {},
    onGestureEnd: (ZoomData) -> Unit = {}
)

Parameters

  • initialZoom zoom set initially
  • minZoom minimum zoom value this Composable can possess
  • maxZoom maximum zoom value this Composable can possess
  • clip whether image should be clip to bounds of Image
  • clipTransformToContentScale when set true zoomable image takes borders of image drawn while zooming in. [contentScale] determines whether will be empty spaces on edges of Composable
  • limitPan limits pan to bounds of parent Composable. Using this flag prevents creating empty space on sides or edges of parent.
  • consume flag to prevent other gestures such as scroll, drag or transform to get event propagations
  • zoomable when set to true zoom is enabled
  • pannable when set to true pan is enabled
  • rotatable when set to true rotation is enabled
  • onGestureStart callback to to notify gesture has started and return current ZoomData of this modifier
  • onGesture callback to notify about ongoing gesture and return current ZoomData of this modifier
  • onGestureEnd callback to notify that gesture finished and return current ZoomData of this modifier

Modifier.enhancedZoom()

Modifier that zooms in or out of Composable set to. This zoom modifier has option to move back to bounds with an animation or option to have fling gesture when user removes from screen while velocity is higher than threshold to have smooth touch effect.

fun Modifier.enhancedZoom(
    key: Any? = Unit,
    clip: Boolean = true,
    enhancedZoomState: EnhancedZoomState,
    enabled: (Float, Offset, Float) -> Boolean = DefaultEnabled,
    zoomOnDoubleTap: (ZoomLevel) -> Float = enhancedZoomState.DefaultOnDoubleTap,
    onGestureStart: ((EnhancedZoomData) -> Unit)? = null,
    onGesture: ((EnhancedZoomData) -> Unit)? = null,
    onGestureEnd: ((EnhancedZoomData) -> Unit)? = null,
)

Parameters

  • key is used for [Modifier.pointerInput] to restart closure when any keys assigned change
  • clip when set to true clips to parent bounds. Anything outside parent bounds is not drawn empty space on sides or edges of parent.
  • enhancedZoomState State of the zoom that contains option to set initial, min, max zoom, enabling rotation, pan or zoom and contains current [EnhancedZoomData]event propagations. Also contains [Rect] of visible area based on pan, zoom and rotation
  • zoomOnDoubleTap lambda that returns current [ZoomLevel] and based on current level enables developer to define zoom on double tap gesture
  • enabled lambda can be used selectively enable or disable pan and intercepting with scroll, drag or lists or pagers using current zoom, pan or rotation values
  • onGestureStart callback to to notify gesture has started and return current [EnhancedZoomData] of this modifier
  • onGesture callback to notify about ongoing gesture and return current [EnhancedZoomData] of this modifier
  • onGestureEnd callback to notify that gesture finished return current [EnhancedZoomData] of this modifier

EnhancedZoomState

Create and [remember] the [EnhancedZoomState] based on the currently appropriate transform configuration to allow changing pan, zoom, and rotation. Allows to change zoom, pan, translate, or get current state by calling methods on this object. To be hosted and passed to [Modifier.enhancedZoom]. Also contains [EnhancedZoomData] about current transformation area of Composable and visible are of image being zoomed, rotated, or panned. If any animation is going on current [EnhancedZoomState.isAnimationRunning] is true and [EnhancedZoomData] returns rectangle that belongs to end of animation.

fun Modifier.enhancedZoom(
    key: Any? = Unit,
    clip: Boolean = true,
    enhancedZoomState: EnhancedZoomState,
    enabled: (Float, Offset, Float) -> Boolean = DefaultEnabled,
    zoomOnDoubleTap: (ZoomLevel) -> Float = enhancedZoomState.DefaultOnDoubleTap,
    onGestureStart: ((EnhancedZoomData) -> Unit)? = null,
    onGesture: ((EnhancedZoomData) -> Unit)? = null,
    onGestureEnd: ((EnhancedZoomData) -> Unit)? = null,
)

Parameters

  • initialZoom zoom set initially
  • minZoom minimum zoom value
  • maxZoom maximum zoom value
  • fling when set to true dragging pointer builds up velocity. When last pointer leaves Composable a movement invoked against friction till velocity drops below to threshold
  • moveToBounds when set to true if image zoom is lower than initial zoom or panned out of image boundaries moves back to bounds with animation.
  • zoomable when set to true zoom is enabled
  • pannable when set to true pan is enabled
  • rotatable when set to true rotation is enabled
  • limitPan limits pan to bounds of parent Composable. Using this flag prevents creating empty space on sides or edges of parent

EnhancedZoomableImage

Zoomable image that zooms in and out in [ [minZoom], [maxZoom] ] interval and pans zoomed image based on pointer position. Double tap gestures reset image translation and zoom to default values with animation. Difference between ZoomaableImage and EnhancedZoomableImage is this version can animate back to bounds and have fling gesture that doesn't stop movement when last pointer is up but continues motion agains friction.

moveToBound is true image moves to bounds when moved out of bounds. When fling is set to true image moves until velocity drops below threshold.

@Composable
fun EnhancedZoomableImage(
    modifier: Modifier = Modifier,
    imageBitmap: ImageBitmap,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    contentDescription: String? = null,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null,
    filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
    initialZoom: Float = 1f,
    minZoom: Float = .5f,
    maxZoom: Float = 5f,
    limitPan: Boolean = true,
    fling: Boolean = false,
    moveToBounds: Boolean = true,
    zoomable: Boolean = true,
    pannable: Boolean = true,
    rotatable: Boolean = false,
    clip: Boolean = true,
    enabled: (Float, Offset, Float) -> Boolean = DefaultEnabled,
    zoomOnDoubleTap: (ZoomLevel) -> Float = DefaultOnDoubleTap,
    clipTransformToContentScale: Boolean = false,
    onGestureStart: ((EnhancedZoomData) -> Unit)? = null,
    onGesture: ((EnhancedZoomData) -> Unit)? = null,
    onGestureEnd: ((EnhancedZoomData) -> Unit)? = null
)

Parameters

  • initialZoom zoom set initially
  • minZoom minimum zoom value this Composable can possess
  • maxZoom maximum zoom value this Composable can possess
  • limitPan limits pan to bounds of parent Composable. Using this flag prevents creating empty space on sides or edges of parent.
  • fling when set to true dragging pointer builds up velocity. When last pointer leaves Composable a movement invoked against friction till velocity drops down to threshold
  • moveToBounds when set to true if image zoom is lower than initial zoom or panned out of image boundaries moves back to bounds with animation.
  • zoomable when set to true zoom is enabled
  • pannable when set to true pan is enabled
  • rotatable when set to true rotation is enabled
  • clip when set to true clips to parent bounds. Anything outside parent bounds is not drawn
  • clipTransformToContentScale when set true zoomable image takes borders of image drawn while zooming in. [contentScale] determines whether will be empty spaces on edges of Composable
  • zoomOnDoubleTap lambda that returns current [ZoomLevel] and based on current level enables developer to define zoom on double tap gesture
  • enabled lambda can be used selectively enable or disable pan and intercepting with scroll, drag or lists or pagers using current zoom, pan or rotation values
  • onGestureStart callback to to notify gesture has started and return current ZoomData of this modifier
  • onGesture callback to notify about ongoing gesture and return current ZoomData of this modifier
  • onGestureEnd callback to notify that gesture finished and return current ZoomData of this modifier

Modifier.animatedZoom()

Modifier that zooms in or out of Composable set to. This zoom modifier has option to move back to bounds with an animation or option to have fling gesture when user removes from screen while velocity is higher than threshold to have smooth touch effect.

Difference between Modifier.enhancedZoom() and Modifier.animatedZoom() is enhanced zoom uses Bitmap dimensions and returns a callback that returns [EnhancedZoomData] that contains visible image area which is suitable for crop while Modifier.animatedZoom() requires dimensions of Composable to have valid pan limiting behavior. More suitable for zooming Composables while enhanced zoom is more suitable for image zooming.

fun Modifier.animatedZoom(
    vararg keys: Any?,
    clip: Boolean = true,
    animatedZoomState: AnimatedZoomState,
    enabled: (Float, Offset, Float) -> Boolean = DefaultEnabled,
    zoomOnDoubleTap: (ZoomLevel) -> Float = animatedZoomState.DefaultOnDoubleTap,
)

Parameters

  • keys are used for [Modifier.pointerInput] to restart closure when any keys assigned change
  • clip when set to true clips to parent bounds. Anything outside parent bounds is not drawn
  • animatedZoomState State of the zoom that contains option to set initial, min, max zoom, enabling rotation, pan or zoom
  • zoomOnDoubleTap lambda that returns current [ZoomLevel] and based on current level enables developer to define zoom on double tap gesture
  • enabled lambda can be used selectively enable or disable pan and intercepting with scroll, drag or lists or pagers using current zoom, pan or rotation values

AnimatedZoomState

Create and [remember] the [AnimatedZoomState] based on the currently appropriate transform configuration to allow changing pan, zoom, and rotation.

Allows to change zoom, pan, translate, or get current state by calling methods on this object. To be hosted and passed to [Modifier.animatedZoom].

@Composable
fun rememberAnimatedZoomState(
    contentSize: DpSize = DpSize.Zero,
    initialZoom: Float = 1f,
    minZoom: Float = 1f,
    maxZoom: Float = 5f,
    fling: Boolean = true,
    moveToBounds: Boolean = false,
    zoomable: Boolean = true,
    pannable: Boolean = true,
    rotatable: Boolean = false,
    limitPan: Boolean = true,
    key1: Any? = Unit
)

Parameters

  • contentSize when the content that will be zoomed is not parent pass child size to bound content correctly inside parent. If parent doesn't have any content this parameter is not required
  • initialZoom zoom set initially
  • minZoom minimum zoom value
  • maxZoom maximum zoom value
  • fling when set to true dragging pointer builds up velocity. When last
  • pointer leaves Composable a movement invoked against friction till velocity drops below to threshold
  • moveToBounds when set to true if image zoom is lower than initial zoom or panned out of image boundaries moves back to bounds with animation.
  • zoomable when set to true zoom is enabled
  • pannable when set to true pan is enabled
  • rotatable when set to true rotation is enabled
  • limitPan limits pan to bounds of parent Composable. Using this flag prevents creating empty space on sides or edges of parent

AnimatedZoomLayout

Layout that can zoom, rotate, pan its content with fling and moving back to bounds animation.

@Composable
fun AnimatedZoomLayout(
    modifier: Modifier = Modifier,
    clip: Boolean = true,
    initialZoom: Float = 1f,
    minZoom: Float = 1f,
    maxZoom: Float = 3f,
    fling: Boolean = true,
    moveToBounds: Boolean = false,
    zoomable: Boolean = true,
    pannable: Boolean = true,
    rotatable: Boolean = false,
    limitPan: Boolean = true,
    enabled: (Float, Offset, Float) -> Boolean = DefaultEnabled,
    zoomOnDoubleTap: (ZoomLevel) -> Float = DefaultOnDoubleTap,
    content: @Composable () -> Unit
)

Parameters

  • clip when set to true clips to parent bounds. Anything outside parent bounds is not
  • drawn
  • minZoom minimum zoom value
  • maxZoom maximum zoom value
  • fling when set to true dragging pointer builds up velocity. When last pointer leaves Composable a movement invoked against friction till velocity drops below to threshold
  • moveToBounds when set to true if image zoom is lower than initial zoom or panned out of image boundaries moves back to bounds with animation.
  • zoomable when set to true zoom is enabled
  • pannable when set to true pan is enabled
  • rotatable when set to true rotation is enabled
  • limitPan limits pan to bounds of parent Composable. Using this flag prevents creating empty space on sides or edges of parent
  • zoomOnDoubleTap lambda that returns current [ZoomLevel] and based on current level enables developer to define zoom on double tap gesture
  • enabled lambda can be used selectively enable or disable pan and intercepting with scroll, drag or lists or pagers using current zoom, pan or rotation values

More Repositories

1

Jetpack-Compose-Tutorials

πŸš€πŸ§¨πŸ“ Series of Tutorials to learn about Jetpack Compose with subjects Material Widgets, Layout, SubcomposeLayout, custom layouts, State, custom rememberable, recomposition, LaunchedEffect, side-effects, Gesture, Animation, Navigation, Canvas, UIs like whatsapp and others.
Kotlin
2,797
star
2

Animation-Tutorials

πŸ­πŸš€πŸ’— Tutorials about animations with Animators, Animated Vector Drawables, Shared Transitions, and more
Kotlin
803
star
3

NavigationComponents-Tutorials

Tutorials about Navigation Components to learn using nav graphs, adding top menus, passing arguments via safe args, combining with different Material Design widgets such as BottomNavigationView, Toolbar, ViewPager2, TabLayout and dynamic feature module navigation with DynamicNavHostFragment and examining Memory Leaks.
Kotlin
393
star
4

Compose-Cropper

πŸš€πŸžβœ‚οΈ Image cropper that can crop with static, dynamic crop behavior, can use customizable shapes, vectors, and other png files as mask to crop with various customizations
Kotlin
362
star
5

PropertyFindAR

🏘 πŸŽƒ Real Estate Sample App with RxJava3+Coroutines Flow, Dynamic Feature Modules, Dagger Hilt, Offline First, ConcatAdapter, Animations and tests for Room, Retrofit, useCase and ViewModels with TDD.
Kotlin
263
star
6

Compose-Colorful-Sliders

πŸš€πŸŒˆ 😍 Colorful Sliders written with Jetpack Compose that enliven default sliders with track and thumb dimensions, and gradient colors, borders, labels on top or at the bottom move with thumb and ColorfulIconSlider that can display emoji or any Composable as thumb
Kotlin
194
star
7

Compose-BeforeAfter

πŸš€πŸŒ†πŸ™ Display differences or animate progress between 2 images or Composables with overlay and customization options, zoom, pan gestures, and progress to observe properties for animating before-after progress
Kotlin
159
star
8

Toolbar-Samples

Toolbar Samples with TabLayout, CollapsingToolbarLayout and scroll flags, BottomNavigationView, BottomAppBarLayout and Window insets
Kotlin
153
star
9

Compose-Screenshot

πŸš€πŸ“Έ Screenshot Composables and convert to Bitmap or ImageBitmap on user action or periodically.
Kotlin
136
star
10

Compose-Drawing-App

βœοΈπŸš€ Drawing app written with Jetpack Compose Canvas. Draw using touch down, move and up events.Using array of paths to have erase, undo, or redo actions and set properties for path that will be drawn next separately.
Kotlin
97
star
11

Compose-Extended-Gestures

Counterpart of onTouchEvent, TouchDelegate, Transform gestures that notifies start, end, main pointer, pointers and option to consume PointerInputChange which defines whether other gestures should receive or not.
Kotlin
93
star
12

CoroutinesAndFlowTutorials

Series of Tutorials about Coroutines and Flow with Retrofit, Room, and Unit tests.
Kotlin
90
star
13

Compose-AnimatedList

πŸš€πŸ“±πŸ’–Animated LazyColumn/Row changes scale/color with animation and have a current selected item like a Pager. An elegant alternative for selecting from a list
Kotlin
85
star
14

Compose-Bubble

πŸš€πŸ’¬πŸ«§ Speech/Chat bubble written with Jetpack Compose and canvas with various properties such as arrow width, height, background color, shadow to create similar bubbles whatsapp, telegram or others have.
Kotlin
81
star
15

Posts-MVVM-DaggerHilt-Dynamic-Feature-RxJava3-Flow-Sample

Posts Api sample with Kotlin RxJava3/Coroutines Flow, Clean Architecture, Offline first/last with Room + Retrofit2, Dagger Hilt, Dynamic Feature Modules, Static Code Analysis, Gradle DSL, MockK+ MockWebServer with Test Driven Development including Api and Database tests
Kotlin
70
star
16

Compose-Color-Picker-Bundle

πŸš€πŸŒˆ 🎨 Collection of Color Pickers written with Jetpack Compose with solid Color or Gradient with type, tile mode, and color stops in HSL/HSV/RGB models with Colorful Sliders, displays, and many customization options.
Kotlin
69
star
17

Flexible-Chat-Box

Flexible chat row written with Jetpack Compose that positions message and message status based on number of message lines, message width and parent width. And resizable Subcomposelayout that remasures sibling composables to match their widths' to longest composable that matches quote and message width to max width.
Kotlin
55
star
18

Compose-ProgressIndicator

πŸš€πŸš₯β˜„οΈ Customizable progress indicators like on ios/mac/web, circle, scaled circle, gooey(sticky) indicators and dot indicators written with Jetpack Compose
Kotlin
52
star
19

Compose-Zoom

πŸš€πŸžπŸ” Zoom Modifiers, zoomable image and layouts with limit pan bounds, fling and moving back to valid bounds and callbacks that return current transformation or visible image section
Kotlin
51
star
20

Compose-RatingBar

πŸš€β­οΈπŸ‘ Rating bar to set fixed value or change rating using gestures with png or vector drawables and shimmer effect option
Kotlin
48
star
21

Compose-Extended-Colors

πŸš€πŸŒˆβ™Ύ Utility library that expands Compose Colors with Material Design2 colors, color swatches, Material Design 3 Tonal Palettes, color names, and utility functions to convert between HSL, HSV, RGB, HCT models and to HEX or from HEX
Kotlin
41
star
22

Compose-Color-Detector

πŸš€πŸŒˆπŸ” Detect colors from image or your screen after taking it's screenshot and get details as name, hex code, RGB, HSL. Written with Jetpack Compose and Material Design 3
Kotlin
28
star
23

Unit-Test-Tutorials

Series of Tutorials for Unit Testing in Java and Kotlin using JUnit4, JUnit5, Mockito, MockK and Test Driven Development
Kotlin
24
star
24

Android-DaggerHilt-DynamicFetureModule-Boilerplate

Boilerplate to create empty project with Dagger Hilt, Dynamic Feature modules, MVVM, RxJava, Coroutines with modularization
Kotlin
18
star
25

Dagger2-Tutorials

Series of tutorials for learning Dagger2, including dagger hilt, dynamic feature, dagger-android, dependent components, subcomponents and more
Kotlin
18
star
26

Compose-PagerIndicator

πŸš€πŸ“’πŸ“ Indicators for Horizontal or Vertical Pager with different orientation, color, size options and optional touch feature.
Kotlin
15
star
27

Kotlin-Tutorials

Series of Kotlin Tutorials
Kotlin
13
star
28

BubbleLayout

πŸ’¬ Chat/Speech bubble layout with various properties such as arrow width, height, background color, shadow to create similar bubbles whatsapp, telegram or others have.
Kotlin
11
star
29

MVVM-Tutorials

Series of tutorials about MVVM, data binding and Room and LiveData.
Java
10
star
30

Compose-Badge

βœοΈπŸ“Œ Dynamic Badge with customizable features as max number before displaying with +, color, shadow, border, corner radius, font properties and more written with Jetpack Compose. Displays numbers either in circle or rounded rectangle shape based on badge count and selected threshold to transform from circle to rounded rectangle.
Kotlin
10
star
31

SmartToolFactory

10
star
32

SAF-and-Scoped-Storage-Tutorials

Tutorials, utilities and playground for storing files with File, DocumentFile and Storage Access Framework
Java
9
star
33

BadgeTextView

βœ…βœοΈπŸ“Œ Badge TextView for Android to draw numbers on a TextView which is customizable and scalable. Displays numbers either as circle or rounded rectangle depending on badge count and selected threshold to transform from circle to rounded rectangle.
Kotlin
9
star
34

Compass-with-pixel-perfect

Elegant Compass View uses percentages instead of fixed values to draw components to have similar scales in both portrait and landscape orientations.
Kotlin
8
star
35

DataStructuresAndAlgorithmsPlayground

Playground fo data structures and algorithms
Kotlin
6
star
36

Transactional-Key-Value-Store

Transactional Key Value Store written with Jetpack Compose
Kotlin
5
star
37

My-Market-App

Android Challange 2019 - Market App with Kotlin, Room, Retrofit, Dagger, DataBinding, MVVM Clean Architecture with offline first
Kotlin
5
star
38

Static-Code-Analysis

Playground to test KtLint, Detekt, Git Hooks, Kotlin DSL
Kotlin
4
star
39

Github-Example

Github Example with MVVM, Dagger, RxJava, Retrofit, Navigation Components written with TDD
Kotlin
4
star
40

PhoneNumberCheck

PhoneUtilTest
Kotlin
3
star
41

The-Movie-DB-Example

Movie App Sample with MVVM clean arcitecture, Dagger2, Retrofit, RxJava2, DataBinding and Pagination
Kotlin
3
star
42

Room-Persistence-Library-Tutorials

Series of Tutorials about Room Persistance Library Tutorials
Java
2
star
43

RxJava-Tutorials

Tutorials about RxJava2
Kotlin
2
star
44

HopinStream

Hopin virtual event sample
Kotlin
2
star
45

Dynamic-Features-Tutorial

Series of tutorials about dynamic features and split install
Kotlin
2
star
46

Paging-Library-Tutorials

Paging Library Tutorials with only DB, only network and DB + Network
Kotlin
1
star
47

Bluetooth-LE-Smart-Tutorials

Tutorials about Bluetooth LE
Java
1
star
48

RxAndroid-Kotlin-Tutorials

RxJava Tutorials in Android Environment
Kotlin
1
star
49

RxJava-Style-LiveData-And-Flow-TestObserver

TestObserver class for LiveData to test multiple values like ViewState such as loading, and result states or multiple post and setValues
Kotlin
1
star
50

Answers-for-3-algorithm-questions

Kotlin
1
star
51

Flavors-and-Server-Driven-UI

Sample to create UI elements and enable/disable features based on flavors and Server driven updates. Create new UI or change position of elements based on parsing JSON filed downloaded by remote service such as Firebase or dedicated domain.
Kotlin
1
star