Mobile Development 16 min read

Custom Stock K-Line Chart with Jetpack Compose: Drawing and Gesture Handling

This article demonstrates how to build a custom stock K-line chart in Android using Jetpack Compose, covering the transition from traditional View drawing to Compose's Canvas API, detailed code for rendering, and implementing drag, long‑press, and pinch‑zoom gestures with state‑driven UI updates.

Snowball Engineer Team
Snowball Engineer Team
Snowball Engineer Team
Custom Stock K-Line Chart with Jetpack Compose: Drawing and Gesture Handling

Jetpack Compose has been officially released for over a month, and this tutorial uses a custom stock K-line chart to teach Compose drawing and gesture handling. Compose replaces XML layouts and View inheritance with declarative UI and composable functions, offering less code, real‑time previews, and flexible rendering.

The article first outlines how to implement the same chart using a traditional Android View: inherit View , override onDraw , draw the frame, candles, axes, and handle drag, zoom, and long‑press gestures. Sample code shows the onDraw method and touch event handling.

Next, the Compose implementation is introduced. Instead of extending View , a Canvas composable is used. Two overloads of Canvas are shown, one with a content description. The modifier defines size, style, and gestures, while the onDraw lambda provides a DrawScope for drawing operations.

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    initCandleData();
    // 1.绘制边框,固定不变
    drawFrame(canvas);
    // 2.绘制蜡烛
    drawCandles(canvas);
    // 3.在蜡烛图后绘制y轴坐标,避免被蜡烛图遮挡
    drawYValue(canvas);
    if (isShowCross) {
        // 4.显示十字交叉线
        drawCross(canvas);
    }
}

The Compose drawing steps include calculating canvas dimensions, determining candle width and spacing, computing visible price range, and then drawing the frame, candles, and Y‑axis values. Code snippets illustrate these calculations and the actual drawing commands using drawRect , drawLine , and native canvas text rendering.

.drawWithContent {
    drawContent()
    if (isShowCross) {
        drawIntoCanvas {
            val priceStr = yToPrice(crossY, yMaxValue, yMinValue, height).toString()
            val textWidth = yValuePaint.measureText(priceStr)
            // 绘制十字光标
            it.drawLine(Offset(0f, crossY), Offset(width - textWidth, crossY), crossPaint)
            it.drawLine(Offset(crossX, 0f), Offset(crossX, height), crossPaint)
            // 绘制交叉线上的价格
            yValuePaint.color = Color.Blue.toArgb()
            it.nativeCanvas.drawText(priceStr, width - textWidth, crossY, yValuePaint)
        }
    }
}

Gesture handling in Compose is performed with the pointerInput modifier and the awaitPointerEventScope coroutine. The article explains how to process single‑finger drag, long‑press, and multi‑finger pinch‑zoom by examining PointerEvent and PointerInputChange objects, updating state variables such as indexStart , indexEnd , scale , and crosshair coordinates.

.pointerInput(Unit) {
    forEachGesture {
        awaitPointerEventScope {
            while (true) {
                val event: PointerEvent = awaitPointerEvent(PointerEventPass.Final)
                if (event.changes.size == 1) {
                    // single‑finger logic (long press, drag, etc.)
                } else if (event.changes.size > 1) {
                    // multi‑finger zoom logic
                }
            }
        }
    }
}

State variables declared with remember { mutableStateOf(...) } trigger recomposition when gestures modify them, automatically updating the UI without explicit invalidate() calls. The article concludes that the custom K‑line chart is complete, and the same approach can be adapted for intraday charts.

References are provided for Compose custom drawing and gesture documentation, and a GitHub repository link offers the full source code.

Finally, the article includes a recruitment notice for engineers interested in the Snowball platform.

AndroidcanvasJetpack ComposeCustom Viewgesture handlingK-Line Chart
Snowball Engineer Team
Written by

Snowball Engineer Team

Proactivity, efficiency, professionalism, and empathy are the core values of the Snowball Engineer Team; curiosity, passion, and sharing of technology drive their continuous progress.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.