diff --git a/compose/src/main/java/com/qmuiteam/compose/ex/DrawScopeEx.kt b/compose/src/main/java/com/qmuiteam/compose/ex/DrawScopeEx.kt new file mode 100644 index 00000000..0823998d --- /dev/null +++ b/compose/src/main/java/com/qmuiteam/compose/ex/DrawScopeEx.kt @@ -0,0 +1,45 @@ +package com.qmuiteam.compose.ex + +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.qmuiteam.compose.ui.qmuiSeparatorColor + +fun DrawScope.drawTopSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { + drawLine( + color = color, + start = Offset(insetStart.toPx(), 0f), + end = Offset(size.width - insetEnd.toPx(), 0f), + cap = StrokeCap.Square + ) +} + +fun DrawScope.drawBottomSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { + drawLine( + color = color, + start = Offset(insetStart.toPx(), size.height), + end = Offset(size.width - insetEnd.toPx(), size.height), + cap = StrokeCap.Square + ) +} + +fun DrawScope.drawLeftSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { + drawLine( + color = color, + start = Offset(0f, insetStart.toPx()), + end = Offset(0f, size.height - insetEnd.toPx()), + cap = StrokeCap.Square + ) +} + +fun DrawScope.drawRightSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { + drawLine( + color = color, + start = Offset(size.width, insetStart.toPx()), + end = Offset(size.width, size.height - insetEnd.toPx()), + cap = StrokeCap.Square + ) +} \ No newline at end of file diff --git a/compose/src/main/java/com/qmuiteam/compose/modal/QMUIDialog.kt b/compose/src/main/java/com/qmuiteam/compose/modal/QMUIDialog.kt index 8cf7d089..26fda810 100644 --- a/compose/src/main/java/com/qmuiteam/compose/modal/QMUIDialog.kt +++ b/compose/src/main/java/com/qmuiteam/compose/modal/QMUIDialog.kt @@ -6,6 +6,10 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -23,6 +27,7 @@ import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.qmuiteam.compose.ui.qmuiCommonHorSpace +import com.qmuiteam.compose.ui.qmuiDialogVerEdgeProtectionMargin import com.qmuiteam.compose.ui.qmuiPrimaryColor val DefaultDialogPaddingHor = 20.dp @@ -32,7 +37,7 @@ val DefaultDialogPaddingHor = 20.dp fun QMUIDialog( modal: QMUIModal, horEdge: Dp = qmuiCommonHorSpace, - verEdge: Dp = 20.dp, + verEdge: Dp = qmuiDialogVerEdgeProtectionMargin, widthLimit: Dp = 360.dp, radius: Dp = 2.dp, background: Color = Color.White, @@ -93,6 +98,25 @@ fun QMUIDialogMsg( } } +@Composable +fun QMUIDialogList( + modal: QMUIModal, + maxHeight: Dp = Dp.Unspecified, + state: LazyListState = rememberLazyListState(), + contentPadding: PaddingValues = PaddingValues(vertical = 8.dp), + children: LazyListScope.() -> Unit +) { + LazyColumn( + state = state, + modifier = Modifier + .fillMaxWidth() + .heightIn(0.dp, maxHeight), + contentPadding = contentPadding + ) { + children() + } +} + @Composable fun QMUIDialogTitle( text: String, @@ -161,7 +185,7 @@ fun QMUIDialogAction( color: Color = qmuiPrimaryColor, fontWeight: FontWeight? = FontWeight.Bold, fontFamily: FontFamily? = null, - paddingVer:Dp = 9.dp, + paddingVer: Dp = 9.dp, paddingHor: Dp = 14.dp, enabled: Boolean = true, onClick: () -> Unit @@ -194,8 +218,8 @@ fun View.qmuiDialog( maskCancellable: Boolean = true, modalHostProvider: ModalHostProvider = DefaultModalHostProvider, animationDurationMillis: Int = 300, - horEdge: Dp = 20.dp, - verEdge: Dp = 20.dp, + horEdge: Dp = qmuiCommonHorSpace, + verEdge: Dp = qmuiDialogVerEdgeProtectionMargin, widthLimit: Dp = 360.dp, radius: Dp = 12.dp, background: Color = Color.White, diff --git a/compose/src/main/java/com/qmuiteam/compose/ui/DefaultConfig.kt b/compose/src/main/java/com/qmuiteam/compose/ui/DefaultConfig.kt index 3a46d1fd..a20770a5 100644 --- a/compose/src/main/java/com/qmuiteam/compose/ui/DefaultConfig.kt +++ b/compose/src/main/java/com/qmuiteam/compose/ui/DefaultConfig.kt @@ -17,4 +17,7 @@ val qmuiCommonHorSpace = 20.dp val qmuiScrollAlphaChangeMaxOffset = 20.dp +val qmuiDialogVerEdgeProtectionMargin = 44.dp + + diff --git a/compose/src/main/java/com/qmuiteam/compose/ui/QMUIIcon.kt b/compose/src/main/java/com/qmuiteam/compose/ui/QMUIIcon.kt new file mode 100644 index 00000000..1345d9a5 --- /dev/null +++ b/compose/src/main/java/com/qmuiteam/compose/ui/QMUIIcon.kt @@ -0,0 +1,57 @@ +package com.qmuiteam.compose.ui + +import androidx.compose.foundation.Image +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import com.qmuiteam.compose.R + +@Composable +fun QMUIChevronIcon(tint: Color? = null) { + Image( + painter = painterResource(id = R.drawable.ic_qmui_chevron), + contentDescription = "", + colorFilter = tint?.let { ColorFilter.tint(it) } + ) +} + +enum class CheckStatus { + none, partial, checked +} + +@Composable +fun QMUICheckBox( + status: CheckStatus = CheckStatus.none, + isEnabled: Boolean = true, + tint: Color? +) { + val icon = when (status) { + CheckStatus.checked -> R.drawable.ic_qmui_checkbox_checked + CheckStatus.partial -> R.drawable.ic_qmui_checkbox_partial + else -> R.drawable.ic_qmui_checkbox_normal + } + Image( + painter = painterResource(id = icon), + contentDescription = "", + colorFilter = tint?.let { ColorFilter.tint(it) }, + modifier = Modifier.let { + if (isEnabled) { + it + } else { + it.alpha(0.5f) + } + } + ) +} + +@Composable +fun QMUIMarkIcon(tint: Color? = null) { + Image( + painter = painterResource(id = R.drawable.ic_qmui_mark), + contentDescription = "", + colorFilter = tint?.let { ColorFilter.tint(it) } + ) +} \ No newline at end of file diff --git a/compose/src/main/java/com/qmuiteam/compose/ui/QMUIListCommonItem.kt b/compose/src/main/java/com/qmuiteam/compose/ui/QMUIItem.kt similarity index 67% rename from compose/src/main/java/com/qmuiteam/compose/ui/QMUIListCommonItem.kt rename to compose/src/main/java/com/qmuiteam/compose/ui/QMUIItem.kt index 5698de36..a1801c90 100644 --- a/compose/src/main/java/com/qmuiteam/compose/ui/QMUIListCommonItem.kt +++ b/compose/src/main/java/com/qmuiteam/compose/ui/QMUIItem.kt @@ -12,10 +12,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight @@ -24,53 +21,6 @@ import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -interface QMUIItemAccessory { - @Composable - fun Compose() -} - -class QMUIItemAccessoryChevron(val tint: Color) : QMUIItemAccessory { - @Composable - override fun Compose() { - - } -} - -fun DrawScope.drawTopSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { - drawLine( - color = color, - start = Offset(insetStart.toPx(), 0f), - end = Offset(size.width - insetEnd.toPx(), 0f), - cap = StrokeCap.Square - ) -} - -fun DrawScope.drawBottomSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { - drawLine( - color = color, - start = Offset(insetStart.toPx(), size.height), - end = Offset(size.width - insetEnd.toPx(), size.height), - cap = StrokeCap.Square - ) -} - -fun DrawScope.drawLeftSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { - drawLine( - color = color, - start = Offset(0f, insetStart.toPx()), - end = Offset(0f, size.height - insetEnd.toPx()), - cap = StrokeCap.Square - ) -} - -fun DrawScope.drawRightSeparator(color: Color = qmuiSeparatorColor, insetStart: Dp = 0.dp, insetEnd: Dp = 0.dp) { - drawLine( - color = color, - start = Offset(size.width, insetStart.toPx()), - end = Offset(size.width, size.height - insetEnd.toPx()), - cap = StrokeCap.Square - ) -} @Composable fun QMUIItem( @@ -93,7 +43,7 @@ fun QMUIItem( paddingHor: Dp = qmuiCommonHorSpace, paddingVer: Dp = 12.dp, gapBetweenTitleAndDetail: Dp = 4.dp, - accessory: QMUIItemAccessory? = null, + accessory: @Composable (RowScope.() -> Unit)? = null, drawBehind: (DrawScope.() -> Unit)? = null, onClick: (() -> Unit)? = null ) { @@ -139,6 +89,6 @@ fun QMUIItem( } } - accessory?.Compose() + accessory?.invoke(this) } } \ No newline at end of file diff --git a/compose/src/main/java/com/qmuiteam/compose/ui/QMUITopBar.kt b/compose/src/main/java/com/qmuiteam/compose/ui/QMUITopBar.kt index ff0dee92..2ef2de8d 100644 --- a/compose/src/main/java/com/qmuiteam/compose/ui/QMUITopBar.kt +++ b/compose/src/main/java/com/qmuiteam/compose/ui/QMUITopBar.kt @@ -10,8 +10,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.* import androidx.compose.ui.layout.* import androidx.compose.ui.platform.InspectorInfo @@ -89,7 +87,7 @@ open class QMUITopBarBackIconItem( enable: Boolean = true, onClick: () -> Unit ) : QMUITopBarIconItem( - R.drawable.qmui_icon_topbar_back, + R.drawable.ic_qmui_topbar_back, "返回", tint, pressAlpha, diff --git a/compose/src/main/res/drawable/ic_qmui_checkbox_checked.xml b/compose/src/main/res/drawable/ic_qmui_checkbox_checked.xml new file mode 100644 index 00000000..98f7472c --- /dev/null +++ b/compose/src/main/res/drawable/ic_qmui_checkbox_checked.xml @@ -0,0 +1,12 @@ + + + diff --git a/compose/src/main/res/drawable/ic_qmui_checkbox_normal.xml b/compose/src/main/res/drawable/ic_qmui_checkbox_normal.xml new file mode 100644 index 00000000..354ca8ab --- /dev/null +++ b/compose/src/main/res/drawable/ic_qmui_checkbox_normal.xml @@ -0,0 +1,12 @@ + + + diff --git a/compose/src/main/res/drawable/ic_qmui_checkbox_partial.xml b/compose/src/main/res/drawable/ic_qmui_checkbox_partial.xml new file mode 100644 index 00000000..b84eef7d --- /dev/null +++ b/compose/src/main/res/drawable/ic_qmui_checkbox_partial.xml @@ -0,0 +1,12 @@ + + + diff --git a/compose/src/main/res/drawable/ic_qmui_chevron.xml b/compose/src/main/res/drawable/ic_qmui_chevron.xml new file mode 100644 index 00000000..114badc8 --- /dev/null +++ b/compose/src/main/res/drawable/ic_qmui_chevron.xml @@ -0,0 +1,12 @@ + + + diff --git a/compose/src/main/res/drawable/ic_qmui_mark.xml b/compose/src/main/res/drawable/ic_qmui_mark.xml new file mode 100644 index 00000000..bcf5221a --- /dev/null +++ b/compose/src/main/res/drawable/ic_qmui_mark.xml @@ -0,0 +1,12 @@ + + + diff --git a/compose/src/main/res/drawable/qmui_icon_topbar_back.xml b/compose/src/main/res/drawable/ic_qmui_topbar_back.xml similarity index 100% rename from compose/src/main/res/drawable/qmui_icon_topbar_back.xml rename to compose/src/main/res/drawable/ic_qmui_topbar_back.xml diff --git a/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/QDDialogFragment.kt b/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/QDDialogFragment.kt index 090a2652..b2fecc05 100644 --- a/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/QDDialogFragment.kt +++ b/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/QDDialogFragment.kt @@ -2,18 +2,17 @@ package com.qmuiteam.qmuidemo.fragment import android.widget.Toast import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.rememberScrollState -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalView import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp +import com.qmuiteam.compose.modal.QMUIDialogList import com.qmuiteam.compose.modal.QMUIDialogMsg import com.qmuiteam.compose.modal.QMUIModalAction import com.qmuiteam.compose.modal.qmuiDialog @@ -27,7 +26,7 @@ import com.qmuiteam.qmuidemo.lib.annotation.Widget @Widget(widgetClass = QMUIDialog::class, iconRes = R.mipmap.icon_grid_dialog) @LatestVisitRecord -class QDDialogFragment(): ComposeBaseFragment() { +class QDDialogFragment() : ComposeBaseFragment() { @Composable override fun PageContent() { @@ -37,13 +36,13 @@ class QDDialogFragment(): ComposeBaseFragment() { scrollState = scrollState, title = "QMUIDialog", leftItems = arrayListOf( - QMUITopBarBackIconItem{ + QMUITopBarBackIconItem { popBackStack() } ), rightItems = arrayListOf( - QMUITopBarTextItem("Test"){ - startFragment(QDAboutFragment()) + QMUITopBarTextItem("Test") { + startFragment(QDAboutFragment()) } ) ) @@ -54,38 +53,14 @@ class QDDialogFragment(): ComposeBaseFragment() { .fillMaxWidth() .weight(1f) .background(Color.White) - ){ + ) { item { QMUIItem( title = "消息类型对话框", drawBehind = { drawBottomSeparator(insetStart = qmuiCommonHorSpace, insetEnd = qmuiCommonHorSpace) } - ){ - view.qmuiDialog { modal -> - QMUIDialogMsg(modal, - "这是标题", - "这是一丢丢有趣但是没啥用的内容", - listOf( - QMUIModalAction("取 消") { - it.dismiss() - }, - QMUIModalAction("确 定") { - Toast - .makeText(view.context, "确定啦!!!", Toast.LENGTH_SHORT) - .show() - it.dismiss() - } - ) - ) - }.show() - } - } - - item { - QMUIItem( - title = "列表类型对话框" - ){ + ) { view.qmuiDialog { modal -> QMUIDialogMsg(modal, "这是标题", @@ -105,6 +80,38 @@ class QDDialogFragment(): ComposeBaseFragment() { }.show() } } + + item { + QMUIItem( + title = "列表类型对话框" + ) { + view.qmuiDialog { modal -> + QMUIDialogList(modal, maxHeight = 500.dp) { + items(200){ index -> + QMUIItem(title = "第${index + 1}项") { + Toast.makeText(view.context, "你点了第${index + 1}项", Toast.LENGTH_SHORT).show() + } + } + } + }.show() + } + } + + item { + QMUIItem( + title = "输入类型对话框" + ) { + view.qmuiDialog { modal -> + QMUIDialogList(modal, maxHeight = 500.dp) { + items(200){ index -> + QMUIItem(title = "第${index + 1}项") { + Toast.makeText(view.context, "你点了第${index + 1}项", Toast.LENGTH_SHORT).show() + } + } + } + }.show() + } + } } } }