Итак, вот мой пример кода < /p>
Код: Выделить всё
class ReactMyCamera: ConstraintLayout {
private var viewFinder: PreviewView = PreviewView(context)
private var mCameraProvider: ProcessCameraProvider? = null
private lateinit var cameraExecutor: ExecutorService
private var imageCapture: ImageCapture? = null
private var button: Button = Button(context)
companion object {
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
}
constructor(context: Context) : super(context) {
configureComponent(context)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
configureComponent(context)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
configureComponent(context)
}
private fun configureComponent(context: Context) {
val constraintLayoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
layoutParams = constraintLayoutParams
val constraintSet = ConstraintSet()
constraintSet.clone(this)
viewFinder.id = View.generateViewId()
viewFinder.layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
ConstraintLayout.LayoutParams.MATCH_CONSTRAINT
)
addView(viewFinder)
constraintSet.constrainWidth(viewFinder.id,ConstraintSet.MATCH_CONSTRAINT)
constraintSet.constrainHeight(viewFinder.id,ConstraintSet.MATCH_CONSTRAINT)
constraintSet.connect(viewFinder.id,ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT)
constraintSet.connect(viewFinder.id,ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT)
constraintSet.connect(viewFinder.id,ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP)
constraintSet.connect(viewFinder.id,ConstraintSet.BOTTOM,ConstraintSet.PARENT_ID,ConstraintSet.BOTTOM,200)
button.id = View.generateViewId()
button.text = "Take Photo"
button.layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
button.setBackgroundColor(Color.YELLOW)
button.setTextColor(Color.RED)
addView(button)
constraintSet.constrainWidth(button.id,ConstraintSet.MATCH_CONSTRAINT)
constraintSet.constrainHeight(button.id,ConstraintSet.WRAP_CONTENT)
constraintSet.connect(button.id,ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT)
constraintSet.connect(button.id,ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT)
constraintSet.connect(button.id,ConstraintSet.BOTTOM,ConstraintSet.PARENT_ID,ConstraintSet.BOTTOM,20)
setupLayoutHack()
manuallyLayoutChildren()
constraintSet.applyTo(this)
button.setOnClickListener {
takePhoto()
}
setUpCamera(context)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
manuallyLayoutChildren()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
measureChildren(widthMeasureSpec, heightMeasureSpec)
}
private fun setupLayoutHack() {
Choreographer.getInstance().postFrameCallback(object : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
manuallyLayoutChildren()
viewTreeObserver.dispatchOnGlobalLayout()
Choreographer.getInstance().postFrameCallback(this)
}
})
}
private fun manuallyLayoutChildren() {
for (i in 0 until childCount) {
val child = getChildAt(i)
child.measure(
MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY)
)
child.layout(0, 0, child.measuredWidth, child.measuredHeight)
}
}
....
}
< /code>
Теперь проблема в том, что я не вижу камеру, кнопка занимает всю ширину и высоту, если экран, теперь, когда я использую тот же код в нативном Android, она работает абсолютно нормально < /p>
Клон этого репо < /p>
npm install
cd android
./gradlew generateCodegenArtifactsFromSchema
yarn react-native run-android --active-arch-only
Теперь я решил рефактор кода, чтобы удалить Constraintlayout
Код: Выделить всё
class ReactMyCamera: FrameLayout {
private var viewFinder: PreviewView = PreviewView(context)
private lateinit var button: Button
private var mCameraProvider: ProcessCameraProvider? = null
private lateinit var cameraExecutor: ExecutorService
private var imageCapture: ImageCapture? = null
companion object {
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
}
constructor(context: Context) : super(context) {
configureComponent(context)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
configureComponent(context)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
configureComponent(context)
}
private fun configureComponent(context: Context) {
viewFinder.layoutParams = FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT
)
installHierarchyFitter(viewFinder)
addView(viewFinder)
// Create Button
button = Button(context).apply {
id = View.generateViewId()
text = "Start"
elevation = 2f
layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT
).apply {
gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
bottomMargin = 10
}
}
addView(button)
}
private val REQUIRED_PERMISSIONS = mutableListOf(Manifest.permission.CAMERA).apply {
if (Build.VERSION.SDK_INT
Я также пытался сделать следующие вещи < /p>
1.
override fun requestLayout() {
super.requestLayout()
post(measureAndLayout)
}
private val measureAndLayout = Runnable {
measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
)
layout(left, top, right, bottom)
}
< /code>
[list]
[*] private val measureAndlayout = runnable {
ream (
mameaspec.makemeasperspec(width, mearspec.exactly),
measurespec.makemeaspec-(height.xactly), exactly), exactly), exactly), exactly), exactly) < /br /measerspec.makemeaspec- ceace.xactly). /> Layout (слева, вверху, справа, внизу)
} < /p>
переопределить веселье намеров (WidthMeasurespec: int, heightmeaspec: int) {
var maxwidth = 0
var maxheight = 0
for (i in 0 in gildcount) {br /> gath = 0
for (i in 0 in gildcount) {
gate) {br /> gate) (child.visibility! = Gone) {
child.measure(widthmeasurespec, termespec.unspecifififified)
maxwidth = maxwidth.coerceatleast (child.measuredwidth)
maxheight = maxheight.coerceatles /> val finalwidth = maxwidth.coerceatleasteast (prevededminimumwidth)
val finalheight = maxheight.coerceatleast (prevededminimumheight)
setmeaseRedDimension (finalwidth, finalHeight)
(контекст как TheMedReActContext). /> (контекст как TheMedReactContext) .getNativeModule (uimanagermodule :: class.java)
? Int, справа: int, внизу: int) {
super.onlayout(Changed, слева, вверху, справа, внизу)
вручные /> super.onmeasure(widthmeasurespec, heightmeaspecpec)
measurechildren (widthmeasurespec, heightmeaspec)
} < /p>
< /li>
override fun requestlayout () {br />super.RequestlAyout. /> post (measureAndlayout)
} < /p>
private val measureAndLayout = Runnable {
measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
)
layout(left, top, right, bottom)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var maxWidth = 0
var maxHeight = 0
for (i in 0 until childCount) {
val child = getChildAt(i)
if (child.visibility != GONE) {
child.measure(widthMeasureSpec, MeasureSpec.UNSPECIFIED)
maxWidth = maxWidth.coerceAtLeast(child.measuredWidth)
maxHeight = maxHeight.coerceAtLeast(child.measuredHeight)
}
}
val finalWidth = maxWidth.coerceAtLeast(suggestedMinimumWidth)
val finalHeight = maxHeight.coerceAtLeast(suggestedMinimumHeight)
setMeasuredDimension(finalWidth, finalHeight)
(context as ThemedReactContext).runOnNativeModulesQueueThread {
(context as ThemedReactContext).getNativeModule(UIManagerModule::class.java)
?.updateNodeSize(id, finalWidth, finalHeight)
}
}
Пробое использовал RELATIVELAYOU>
Подробнее здесь: https://stackoverflow.com/questions/796 ... ack-screen