我知道这个问题已经被问过很多次了,我已经提到过这些,但我的用例几乎没有什么不同。我需要允许用户在一个上绘图,ImageBackground
所以我为它创建了自己的原生视图。我不面对这个问题ios
。它只发生在android
. 我的代码中没有注释,这是应用程序出现问题的主要原因。由于这有效ios
而不是有效,android
所以我认为问题可能来自本地,但我仍然无法弄清楚它是什么
这是我的本机android
代码
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
class CanvasManager: SimpleViewManager<CanvasView>() {
override fun createViewInstance(reactContext: ThemedReactContext): CanvasView {
return CanvasView(reactContext)
}
override fun getName(): String {
return "Canvas"
}
}
class CanvasPackage: ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return emptyList()
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return listOf(
CanvasManager()
)
}
}
import android.content.Context
import android.graphics.*
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import androidx.core.content.res.ResourcesCompat
import kotlin.math.abs
private const val STROKE_WIDTH = 12f
class CanvasView(context: Context) : View(context) {
private var path = Path()
private val drawColor = ResourcesCompat.getColor(resources, R.color.colorPaint, null)
private val backgroundColor = ResourcesCompat.getColor(resources, android.R.color.transparent, null)
private lateinit var extraCanvas: Canvas
private lateinit var extraBitmap: Bitmap
private lateinit var frame: Rect
private val paint = Paint().apply {
color = drawColor
isAntiAlias = true
isDither = true
style = Paint.Style.STROKE
strokeJoin = Paint.Join.ROUND
strokeCap = Paint.Cap.ROUND
strokeWidth = STROKE_WIDTH
}
private val touchTolerance = ViewConfiguration.get(context).scaledTouchSlop
private var currentX = 0f
private var currentY = 0f
private var motionTouchEventX = 0f
private var motionTouchEventY = 0f
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
super.onSizeChanged(width, height, oldWidth, oldHeight)
if (::extraBitmap.isInitialized) extraBitmap.recycle()
val spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
rootView.measure(spec, spec);
rootView.layout(0, 0, rootView.measuredWidth, rootView.measuredHeight);
extraBitmap = Bitmap.createBitmap(rootView.width, rootView.height, Bitmap.Config.ARGB_8888)
extraCanvas = Canvas(extraBitmap)
extraCanvas.drawColor(backgroundColor)
frame = Rect(0, 0, width , height )
}
override fun onDraw(canvas: Canvas) {
canvas.drawBitmap(extraBitmap, 0f, 0f, null)
extraCanvas.drawRect(frame, paint)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
motionTouchEventX = event.x
motionTouchEventY = event.y
when (event.action) {
MotionEvent.ACTION_DOWN -> touchStart()
MotionEvent.ACTION_MOVE -> touchMove()
MotionEvent.ACTION_UP -> touchUp()
}
return true
}
private fun touchStart() {
path.reset()
path.moveTo(motionTouchEventX, motionTouchEventY)
currentX = motionTouchEventX
currentY = motionTouchEventY
}
private fun touchMove() {
val dx = abs(motionTouchEventX - currentX)
val dy = abs(motionTouchEventY - currentY)
if (dx >= touchTolerance || dy >= touchTolerance) {
path.quadTo(currentX, currentY, (motionTouchEventX + currentX) / 2, (motionTouchEventY + currentY) / 2)
currentX = motionTouchEventX
currentY = motionTouchEventY
extraCanvas.drawPath(path, paint)
}
invalidate()
}
private fun touchUp() {
path.reset()
}
}
以下是我的反应原生代码
const ChatImageEditingScreen = ({ navigation, route }) => {
return (
<>
<SafeAreaView style={styles.containerStyle}>
<ViewShot ref={imageRef}>
<ImageBackground
source={{
uri: image,
}}
style={styles.imageBackgroundStyle}
>
<ChatImageEditingCenterText
text={text}
color={color}
editText={editText}
/>
<ChatImageEditingCanvas showCanvas={showCanvas} />
</ImageBackground>
</ViewShot>
</SafeAreaView>
//Some other components......
})
import React from "react";
import { requireNativeComponent, StyleSheet, Text } from "react-native";
const Canvas = requireNativeComponent("Canvas");
const ChatImageEditingCanvas = ({ showCanvas }) => {
return (
<Canvas
style={{
...styles.canvasStyle,
height: showCanvas ? null : 0,
}}
/>
);
};
const styles = StyleSheet.create({
canvasStyle: {
flex: 1,
alignItems: "center",
justifyContent: "center",
position: "absolute",
top: 100,
bottom: 100,
left: 0,
right: 0,
backgroundColor: "transparent",
},
});
export default ChatImageEditingCanvas;
对于我的本机ios
代码,我指的是对我有用的https://youtu.be/E2NTCmEsdSE。不知道是什么问题android