Skip to content

Commit

Permalink
feat: Bump Kotlin to 2.0.20, AGP to 8.5.0; Support selectedTextColor;…
Browse files Browse the repository at this point in the history
… Support Adapter for SinglePickerDialog; Add more comment to functions.
  • Loading branch information
oOJohn6Oo committed Sep 7, 2024
1 parent a6179e8 commit 91aae0b
Show file tree
Hide file tree
Showing 36 changed files with 956 additions and 343 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
local.properties

/release
/.kotlin
14 changes: 7 additions & 7 deletions JWheelPicker/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ plugins {
id("com.android.library")
id("kotlin-parcelize")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose")
}

apply(from = "publish.gradle")

android {
Expand All @@ -25,7 +27,7 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
Expand All @@ -34,13 +36,11 @@ android {
buildFeatures {
compose = true
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.3"
}
}

dependencies {
implementation("androidx.compose.material:material:1.5.3")
api("com.github.oOJohn6Oo.BaseAndroid:john-base-compose:1.0.8")
implementation("androidx.compose.material:material:1.7.0")
implementation("androidx.fragment:fragment-ktx:1.8.3")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("com.google.android.material:material:1.12.0")
}
2 changes: 1 addition & 1 deletion JWheelPicker/consumer-rules.pro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-keepclassmembers public class * extends androidx.lifecycle.ViewModel {
public <init>(...);
}
-keepclassmembers public class * extends io.john6.base.compose.picker.dialog.multiple.IMultipleJPickerAdapter {
-keepclassmembers public class * extends io.john6.base.compose.picker.dialog.IJPickerAdapter {
public <init>(...);
}
2 changes: 1 addition & 1 deletion JWheelPicker/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
-keepclassmembers public class * extends androidx.lifecycle.ViewModel {
public <init>(...);
}
-keepclassmembers public class * extends io.john6.base.compose.picker.dialog.multiple.IMultipleJPickerAdapter {
-keepclassmembers public class * extends io.john6.base.compose.picker.dialog.IJPickerAdapter {
public <init>(...);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material.ElevationOverlay
import androidx.compose.material.MaterialTheme
import androidx.compose.material.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlin.math.ln
/**
* Add padding for Bottom section of our view
*/
internal fun Modifier.bottomSafeDrawing(): Modifier = composed {
this.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom))
}

/**
* Some times We do not care the safe area at the horizontal edge, like in dialog
*/
internal fun Modifier.onlyBottomSafeDrawing(): Modifier = composed {
this.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom))
}

@Composable
fun jSurfaceColorAtElevation(
color: Color,
elevationOverlay: ElevationOverlay?,
absoluteElevation: Dp
): Color {
return if (color == MaterialTheme.colors.surface && elevationOverlay != null) {
elevationOverlay.apply(color, absoluteElevation)
} else {
color
}
}


@ReadOnlyComposable
@Composable
fun calculateForegroundColor(backgroundColor: Color, elevation: Dp): Color {
val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
val baseForegroundColor = contentColorFor(backgroundColor)
return baseForegroundColor.copy(alpha = alpha)
}

object JElevationOverlayInBothLightAndDarkMode : ElevationOverlay {
@ReadOnlyComposable
@Composable
override fun apply(color: Color, elevation: Dp): Color {
val foregroundColor = calculateForegroundColor(color, elevation)
return foregroundColor.compositeOver(color)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ package io.john6.base.compose.picker

import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.material.Colors
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Shapes
import androidx.compose.material.Typography
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.intl.Locale
import io.john6.base.compose.picker.bean.JWheelPickerInfo
import io.john6.base.compose.picker.bean.JWheelPickerItemInfo
Expand Down Expand Up @@ -301,10 +307,8 @@ object JDatePickerHelper {
//</editor-fold>

//<editor-fold desc="Formatter related">
var defaultMonthFormatter by lazyMutable {
DateTimeFormatterBuilder().appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
.toFormatter(java.util.Locale.getDefault())
}
var defaultMonthFormatter = DateTimeFormatterBuilder().appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
.toFormatter(java.util.Locale.getDefault())

fun getMonthDisplayText(LocalDateTime: LocalDateTime, language: String): String {
if (!language.equals(defaultMonthFormatter.locale.language, true)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
Expand Down Expand Up @@ -58,6 +59,7 @@ fun JDateWheelPicker(
containerHorizontalPadding: Dp = 0.dp,
enableHapticFeedback: Boolean = true,
textStyle: TextStyle = LocalTextStyle.current,
selectedTextColor: Color = Color.Unspecified,
hapticFeedBackYThreshold: Float = 20f,
@DatePickerMode datePickerMode: Int,
@TimePickerMode timePickerMode: Int,
Expand Down Expand Up @@ -169,6 +171,7 @@ fun JDateWheelPicker(
containerHorizontalPadding = containerHorizontalPadding,
enableHapticFeedback = enableHapticFeedback,
textStyle = textStyle,
selectedTextColor = selectedTextColor,
hapticFeedBackYThreshold = hapticFeedBackYThreshold,
wheelCount = wheelCount,
generateJWheelPickerInfo = generateJWheelPickerInfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
Expand Down Expand Up @@ -42,6 +43,7 @@ fun JMultiWheelPicker(
containerHorizontalPadding: Dp = 0.dp,
enableHapticFeedback: Boolean = true,
textStyle: TextStyle = LocalTextStyle.current,
selectedTextColor: Color = Color.Unspecified,
hapticFeedBackYThreshold: Float = 20f,
wheelCount: Int,
drawOverLay: (ContentDrawScope.(itemHeightPx: Int, edgeOffsetYPx: Float) -> Unit)? = { itemHeightPx, edgeOffsetYPx ->
Expand Down Expand Up @@ -72,6 +74,7 @@ fun JMultiWheelPicker(
wheelIndex = wheelIndex,
itemVerticalPadding = itemVerticalPadding,
enableHapticFeedback = enableHapticFeedback,
selectedTextColor = selectedTextColor,
textStyle = textStyle,
confirmSelectYThreshold = hapticFeedBackYThreshold,
onSelectedItemChanged = onSelectedItemChanged,
Expand All @@ -97,6 +100,7 @@ private fun RowScope.ItemWheelPicker(
enableHapticFeedback: Boolean,
textStyle: TextStyle,
confirmSelectYThreshold: Float,
selectedTextColor: Color = Color.Unspecified,
key: (wheelIndex: Int) -> Any,
onSelectedItemChanged: (JWheelPickerInfo, JWheelPickerItemInfo) -> Unit,
generatePickerData: (wheelIndex: Int) -> JWheelPickerInfo
Expand All @@ -111,6 +115,7 @@ private fun RowScope.ItemWheelPicker(
itemPadding = itemVerticalPadding,
enableHapticFeedback = enableHapticFeedback,
textStyle = textStyle,
selectedTextColor = selectedTextColor,
confirmSelectDistanceThreshold = confirmSelectYThreshold,
itemCount = pickerData.itemCount,
itemData = pickerData.itemData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package io.john6.base.compose.picker

import androidx.annotation.IntDef

@IntDef(value = [JWheelPickerHelper.overlayStyleOvalRectangle, JWheelPickerHelper.overlayStyleLine])
@Retention(AnnotationRetention.RUNTIME)
@IntDef(
value = [JWheelPickerHelper.OVERLAY_STYLE_RECTANGLE, JWheelPickerHelper.OVERLAY_STYLE_LINE]
)
@Retention(AnnotationRetention.SOURCE)
annotation class JPickerOverlayStyle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.john6.base.compose.picker

import android.view.HapticFeedbackConstants
import androidx.annotation.FloatRange
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.interaction.collectIsDraggedAsState
Expand Down Expand Up @@ -51,8 +52,6 @@ import androidx.compose.ui.unit.sp
import io.john6.base.compose.picker.JWheelPickerHelper.drawPickerLineOverlay
import io.john6.base.compose.picker.bean.JWheelPickerItemInfo
import io.john6.base.compose.picker.bean.getText
import io.john6.base.compose.ui.JUtil.disableParentNestedVerticalScroll
import io.john6.base.compose.ui.rememberJMaxScrollFlingBehavior
import kotlinx.coroutines.launch
import kotlin.math.absoluteValue
import kotlin.math.pow
Expand Down Expand Up @@ -164,9 +163,11 @@ fun JWheelPicker(
with(density) { edgeOffsetPx.absoluteValue.toDp() }
}

LaunchedEffect(key1 = itemCount == 0) {
if (itemCount == 0) {
LaunchedEffect(key1 = itemCount){
if(itemCount == 0){
onSelectedItemChanged?.invoke(JWheelPickerItemInfo.EMPTY)
}else{
onSelectedItemChanged?.invoke(itemData(initialIndex))
}
}

Expand All @@ -186,33 +187,27 @@ fun JWheelPicker(
}
}

val performHapticFeedback = remember {
{
if (enableHapticFeedback) {
scope.launch {
localView.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)
}
val performHapticFeedback = {
if (enableHapticFeedback) {
scope.launch {
localView.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)
}
}
}

val getLayoutInfo = remember {
{
lazyListState.layoutInfo
}
val getLayoutInfo = {
lazyListState.layoutInfo
}


// 最终文字样式
val desireTextStyle: (Int) -> TextStyle = if(selectedTextColor == Color.Unspecified){
// 未设置选中文字颜色,则直接为不可变的方法
remember {
{
textStyle
}
{
textStyle
}
}else{ // 设置了选中文字颜色,则需要根据选中下标判断是否需要变色
remember(currentSelectedItemIndex, selectedTextColor, textStyle.color) {
remember(initialIndex, currentSelectedItemIndex, selectedTextColor, textStyle.color) {
{
val finalColor = if (it != currentSelectedItemIndex) {
textStyle.color
Expand All @@ -229,6 +224,7 @@ fun JWheelPicker(
var hasPerformHapticFeedback by remember {
mutableStateOf(true)
}

CompositionLocalProvider(
LocalOverscrollConfiguration provides null
) {
Expand All @@ -242,7 +238,7 @@ fun JWheelPicker(
drawOverLay?.invoke(this, itemHeightPx, edgeOffsetPx)
},
state = lazyListState,
flingBehavior = rememberJMaxScrollFlingBehavior(4000f),
// flingBehavior = rememberJMaxScrollFlingBehavior(4000f),
contentPadding = PaddingValues(vertical = edgeOffsetDp),
) {
items(itemCount, key = { itemData(it) }) {
Expand All @@ -265,7 +261,7 @@ fun JWheelPicker(
drawOverLay?.invoke(this, itemHeightPx, edgeOffsetPx)
},
state = lazyListState,
flingBehavior = rememberJMaxScrollFlingBehavior(4000f),
// flingBehavior = rememberJMaxScrollFlingBehavior(4000f),
contentPadding = PaddingValues(horizontal = edgeOffsetDp),
) {
items(itemCount, key = { itemData(it) }) {
Expand Down Expand Up @@ -321,7 +317,10 @@ private fun VerticalWheelPickerItem(
.fillMaxWidth()
.height(itemHeightDp)
.graphicsLayer {
render3DVerticalItemEffect(index, getLayoutInfo)
render3DVerticalItemEffect(
index,
getLayoutInfo
)
}) {
Text(
text = text,
Expand Down Expand Up @@ -387,7 +386,8 @@ private fun GraphicsLayerScope.render3DVerticalItemEffect(

rotationX = -90 * offset

scaleX = 1 - (offset.absoluteValue).pow(2) * 0.37f
val scale = 1 - (offset.absoluteValue).pow(2) * 0.37f
scaleX = scale

translationY = if (offset == 0f) {
0f
Expand All @@ -396,7 +396,7 @@ private fun GraphicsLayerScope.render3DVerticalItemEffect(
val r = (2f * centerY / Math.PI).toFloat()
// 视觉上的 Y 的坐标位置
val h =
(sin(Math.toRadians(offset.absoluteValue * 90.0)) * r * 1.24).toFloat()
(sin(Math.toRadians(offset.absoluteValue * 90.0)) * r * JWheelPickerHelper.defaultVerticalWheelCurveRate).toFloat()
val diffY = if (offset < 0) {
(centerY - h.absoluteValue) - posY.absoluteValue
} else {
Expand Down Expand Up @@ -427,7 +427,8 @@ private fun GraphicsLayerScope.render3DHorizontalItemEffect(

rotationY = -90 * offset

scaleY = 1 - (offset.absoluteValue).pow(2) * 0.37f
val scale = 1 - (offset.absoluteValue).pow(2) * 0.37f
scaleY = scale

translationX = if (offset == 0f) {
0f
Expand All @@ -436,7 +437,7 @@ private fun GraphicsLayerScope.render3DHorizontalItemEffect(
val r = (2f * centerX / Math.PI).toFloat()
// 视觉上的 Y 的坐标位置
val h =
(sin(Math.toRadians(offset.absoluteValue * 90.0)) * r * 1.24).toFloat()
(sin(Math.toRadians(offset.absoluteValue * 90.0)) * r * JWheelPickerHelper.defaultHorizontalWheelCurveRate).toFloat()
val diffX = if (offset > 0) {
(centerX - h.absoluteValue) - posX.absoluteValue
} else {
Expand Down Expand Up @@ -490,3 +491,18 @@ private val HorizontalParentScrollConsumer = object : NestedScrollConnection {
source: NestedScrollSource
): Offset = available
}


private fun Modifier.disableParentNestedVerticalScroll(disabled: Boolean = true) =
if (disabled) this.nestedScroll(VerticalParentScrollConsumer) else this

private val VerticalParentScrollConsumer = object : NestedScrollConnection {

override suspend fun onPostFling(consumed: Velocity, available: Velocity) = available

override fun onPostScroll(
consumed: Offset,
available: Offset,
source: NestedScrollSource
): Offset = available
}
Loading

0 comments on commit 91aae0b

Please sign in to comment.