Skip to content

Commit

Permalink
简单的触控取色
Browse files Browse the repository at this point in the history
  • Loading branch information
iOrchid committed May 18, 2024
1 parent f23f4b2 commit 3cfdceb
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 3 deletions.
5 changes: 5 additions & 0 deletions compose/src/main/java/org/zhiwei/compose/model/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.zhiwei.compose.screen.basic.material3.Widget_Screen
import org.zhiwei.compose.screen.gesture.Clickable_Screen
import org.zhiwei.compose.screen.gesture.SwipeScroll_Screen
import org.zhiwei.compose.screen.gesture.TapDragGestures_Screen
import org.zhiwei.compose.screen.gesture.TouchImage_Screen
import org.zhiwei.compose.screen.gesture.TransformGestures_Screen
import org.zhiwei.compose.screen.layout_state.ConstraintLayout_Screen
import org.zhiwei.compose.screen.layout_state.Constraints_Screen
Expand Down Expand Up @@ -178,6 +179,10 @@ internal object GestureScreenUIs {
"SwipeScrollable",
"Modifier的一些其他操作手势,侧滑,滚动等。"
) { SwipeScroll_Screen(modifier) },
CourseItemModel(
"TouchOnImage",
"从图片的点击位置,获取触控点的颜色。"
) { TouchImage_Screen(modifier) },
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import androidx.compose.foundation.gestures.AnchoredDraggableState
import androidx.compose.foundation.gestures.DraggableAnchors
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.anchoredDraggable
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
Expand All @@ -16,21 +18,26 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.FractionalThreshold
import androidx.compose.material.Slider
import androidx.compose.material.SwipeProgress
import androidx.compose.material.Text
import androidx.compose.material.rememberSwipeableState
import androidx.compose.material.swipeable
import androidx.compose.material3.Button
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -39,6 +46,8 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.launch
import org.zhiwei.compose.ui.widget.Title_Desc_Text
import org.zhiwei.compose.ui.widget.Title_Sub_Text
import org.zhiwei.compose.ui.widget.Title_Text
Expand All @@ -54,13 +63,24 @@ import kotlin.math.roundToInt
*/
@Composable
internal fun SwipeScroll_Screen(modifier: Modifier = Modifier) {
Column(modifier.fillMaxSize()) {
Column(
modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
Title_Text(title = "Swipeable")
Title_Sub_Text(title = "1. 侧滑事件的简单实现,swipeable操作符,以及替代方式的演示。")
Title_Desc_Text(desc = "swipeable的使用,设置fraction的位置不同,滑动切换的临界点就不一样。")
UI_Swipeable()
Title_Desc_Text(desc = "替代swipeable,使用推荐的新的api,AnchoredDraggable实现相同效果。")
UI_AnchoredDraggable()
Title_Sub_Text(title = "2. 使用Modifier的滑动相关的操作符。")
Title_Desc_Text(desc = "scrollable滑动操作符的使用,简单看一下滚动状态和偏移量变化。")
ScrollableModifierSample()
Title_Desc_Text(desc = "scrollable操作符的scrollable的state可以控制滑动的位置。")
ScrollExample()
//滚动可以嵌套,还有水平,竖直滑动的单独操作符函数。

}
}

Expand Down Expand Up @@ -143,7 +163,7 @@ private fun UI_Swipeable() {
}

//使用AnchoredDraggable代替swipeable实现侧滑效果
@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class)
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun UI_AnchoredDraggable() {
var fraction by remember { mutableFloatStateOf(0.3f) }
Expand Down Expand Up @@ -204,7 +224,75 @@ private fun UI_AnchoredDraggable() {
}
}

private enum class DragValue { Start, Center, End }
@Composable
private fun ScrollableModifierSample() {
var offset by remember { mutableFloatStateOf(0f) }
Box(
Modifier
.fillMaxWidth()
.height(200.dp)
.scrollable(
orientation = Orientation.Vertical,
state = rememberScrollableState { delta ->
offset += delta
delta
}
)
.background(Color.LightGray),
contentAlignment = Alignment.Center
) {
Text(offset.toString())
}
}

@Composable
private fun ScrollExample() {

Column(modifier = Modifier
.fillMaxWidth()
.height(400.dp)) {
val coroutineScope = rememberCoroutineScope()

// Smoothly scroll 100px on first composition
val state = rememberScrollState()

Column(
modifier = Modifier
.background(Color.LightGray)
.fillMaxWidth()
.weight(1f)
.padding(horizontal = 8.dp)
.verticalScroll(state)
) {
repeat(30) {
Text("Item $it", modifier = Modifier.padding(2.dp), fontSize = 20.sp)
}
}

Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
coroutineScope.launch {
state.animateScrollTo(100)
}
}
) {
Text(text = "Smooth Scroll to top")
}


Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
coroutineScope.launch {
state.scrollTo(100)
}
}) {
Text(text = "Scroll to top")
}
}
}



@Preview
Expand Down
134 changes: 134 additions & 0 deletions compose/src/main/java/org/zhiwei/compose/screen/gesture/TouchImage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package org.zhiwei.compose.screen.gesture

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.isUnspecified
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize
import org.zhiwei.compose.R
import org.zhiwei.compose.ui.widget.Title_Sub_Text
import org.zhiwei.compose.ui.widget.Title_Text

/**
* 作者: iOrchid
* 主页: [Github](https://github.com/iOrchid)
* 日期: 2024年05月18日 13:50
* 签名: 天行健,君子以自强不息;地势坤,君子以厚德载物。
* You never know what you can do until you try !
*/
@Composable
internal fun TouchImage_Screen(modifier: Modifier = Modifier) {
Column(modifier.fillMaxSize()) {
Title_Text(title = "ColorPicker")
Title_Sub_Text(title = "从图片Image中,获取触控点的颜色值")
TouchOnImageExample()
}
}

@Composable
private fun TouchOnImageExample() {

val imageBitmap: ImageBitmap = ImageBitmap.imageResource(R.drawable.sexy_girl)

val bitmapWidth = imageBitmap.width
val bitmapHeight = imageBitmap.height

var offsetX by remember { mutableFloatStateOf(0f) }
var offsetY by remember { mutableFloatStateOf(0f) }
var imageSize by remember { mutableStateOf(Size.Zero) }

// These are for debugging
var text by remember { mutableStateOf("") }
var colorAtTouchPosition by remember { mutableStateOf(Color.Unspecified) }

val imageModifier = Modifier
.background(Color.LightGray)
.fillMaxWidth()
// 限定宽高比
.aspectRatio(3f / 4)
.pointerInput(Unit) {
detectTapGestures { offset: Offset ->
// Touch coordinates on image
offsetX = offset.x
offsetY = offset.y

// Scale from Image touch coordinates to range in Bitmap
val scaledX = (bitmapWidth / imageSize.width) * offsetX
val scaledY = (bitmapHeight / imageSize.height) * offsetY

try {
val pixel: Int =
imageBitmap
.asAndroidBitmap()
.getPixel(scaledX.toInt(), scaledY.toInt())


val red = android.graphics.Color.red(pixel)
val green = android.graphics.Color.green(pixel)
val blue = android.graphics.Color.blue(pixel)

text = "图片触控 offsetX:$offsetX, offsetY: $offsetY\n" +
"图片宽: ${imageSize.width}, 高: ${imageSize.height}\n" +
"位图 宽: ${bitmapWidth}, 高: $bitmapHeight\n" +
"scaledX: $scaledX, scaledY: $scaledY\n" +
"red: $red, green: $green, blue: $blue\n"

colorAtTouchPosition = Color(red, green, blue)
} catch (e: Exception) {
println("Exception e: ${e.message}")
}
}
}
.onSizeChanged { imageSize = it.toSize() }

Image(
bitmap = imageBitmap,
contentDescription = null,
modifier = imageModifier.border(2.dp, Color.Red),
contentScale = ContentScale.Crop
)
Text(text = text)
Box(
modifier = Modifier
.then(
if (colorAtTouchPosition.isUnspecified) {
Modifier
} else {
Modifier.background(colorAtTouchPosition)
}
)
.size(100.dp)
)
}

@Preview
@Composable
private fun PreviewTouchImage() {
TouchImage_Screen()
}

0 comments on commit 3cfdceb

Please sign in to comment.