You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中对应JSplitPane的替代方案是什么?

Jetpack Compose 可拖拽分割窗格实现方案

问题背景

  • 在Swing中我使用JSplitPane创建左侧(前导)为树状视图、右侧(尾部)为十六进制查看器的区域,用户可以拖动分割线调整两侧的占用空间。
  • 由于Jetpack Compose目前还相对较新,类似SplitView这类基础组件尚未推出。目前我能找到的最接近的布局组件是Row和Column,但这两个组件原生不支持用户手动拖拽调整尺寸。
  • 需求为不嵌入Swing的JSplitPane,纯Compose实现可拖拽调整比例的分割窗格。
  • 现有公开的旧实现示例存在API废弃问题,且官方发行说明未提及对应替代方案。

纯Compose稳定实现方案

以下实现基于Jetpack Compose 1.4+稳定版API,无废弃接口,同时支持水平/垂直两种分割模式,可配置最小尺寸限制避免子组件被完全隐藏:

核心实现代码

import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.*
import androidx.compose.material.Divider
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp

/**
 * 水平分割窗格:左右分布,拖拽中间分割线调整宽度比例
 * @param modifier 外层修饰符
 * @param initialSplitRatio 初始分割比例,取值0.1~0.9,默认为0.3(左侧占30%宽度)
 * @param minLeftWidth 左侧最小宽度,默认100.dp
 * @param minRightWidth 右侧最小宽度,默认100.dp
 * @param leftContent 左侧区域内容
 * @param rightContent 右侧区域内容
 */
@Composable
fun HorizontalSplitPane(
    modifier: Modifier = Modifier,
    initialSplitRatio: Float = 0.3f,
    minLeftWidth: Float = 100.dp.value,
    minRightWidth: Float = 100.dp.value,
    leftContent: @Composable () -> Unit,
    rightContent: @Composable () -> Unit
) {
    var splitRatio by remember { mutableStateOf(initialSplitRatio.coerceIn(0.1f, 0.9f)) }
    var totalWidth by remember { mutableStateOf(0f) }

    Row(modifier = modifier.fillMaxSize()) {
        Box(Modifier.fillMaxWidth(splitRatio)) {
            leftContent()
        }
        Divider(
            modifier = Modifier
                .width(4.dp)
                .fillMaxHeight()
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        change.consume()
                        val delta = dragAmount.x / totalWidth
                        val newRatio = (splitRatio + delta).coerceIn(
                            minimumValue = minLeftWidth / totalWidth,
                            maximumValue = 1 - (minRightWidth / totalWidth)
                        )
                        splitRatio = newRatio
                    }
                }
        )
        Box(Modifier.fillMaxWidth()) {
            rightContent()
        }
    }.onSizeChanged {
        totalWidth = it.width.toFloat()
    }
}

/**
 * 垂直分割窗格:上下分布,拖拽中间分割线调整高度比例
 * 参数逻辑同水平分割窗格
 */
@Composable
fun VerticalSplitPane(
    modifier: Modifier = Modifier,
    initialSplitRatio: Float = 0.3f,
    minTopHeight: Float = 100.dp.value,
    minBottomHeight: Float = 100.dp.value,
    topContent: @Composable () -> Unit,
    bottomContent: @Composable () -> Unit
) {
    var splitRatio by remember { mutableStateOf(initialSplitRatio.coerceIn(0.1f, 0.9f)) }
    var totalHeight by remember { mutableStateOf(0f) }

    Column(modifier = modifier.fillMaxSize()) {
        Box(Modifier.fillMaxHeight(splitRatio)) {
            topContent()
        }
        Divider(
            modifier = Modifier
                .height(4.dp)
                .fillMaxWidth()
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        change.consume()
                        val delta = dragAmount.y / totalHeight
                        val newRatio = (splitRatio + delta).coerceIn(
                            minimumValue = minTopHeight / totalHeight,
                            maximumValue = 1 - (minBottomHeight / totalHeight)
                        )
                        splitRatio = newRatio
                    }
                }
        )
        Box(Modifier.fillMaxHeight()) {
            bottomContent()
        }
    }.onSizeChanged {
        totalHeight = it.height.toFloat()
    }
}

使用示例

对应左侧树状视图、右侧十六进制查看器的需求,直接调用HorizontalSplitPane传入对应内容即可:

@Composable
fun AppMainContent() {
    HorizontalSplitPane(
        initialSplitRatio = 0.3f,
        leftContent = {
            // 你的树状视图组件
            FileTreeView()
        },
        rightContent = {
            // 你的十六进制查看器组件
            HexViewer()
        }
    )
}

特性说明

  • 纯Compose实现,无需依赖任何第三方库,也不需要嵌入Swing组件
  • 所有API均为Compose稳定版接口,不存在废弃问题
  • 支持自定义初始分割比例、最小宽高限制,适配不同业务场景
  • 分割线自带拖拽反馈,操作逻辑和Swing的JSplitPane保持一致

内容的提问来源于stack exchange,提问作者Hakanai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 14:54:06