1

我知道这个问题已经被问过很多次了,我已经提到过这些,但我的用例几乎没有什么不同。我需要允许用户在一个上绘图,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

4

1 回答 1

0

添加我的回复以防有人在此线程上遇到类似问题:

尝试在视图中呈现 WebView 时遇到相同的错误。原来我必须用 style={{flex: 1}} 设置 View 才能让错误消失

于 2021-10-25T17:42:32.780 回答