journeyapps / zxing-android-embedded

Barcode scanner library for Android, based on the ZXing decoder
https://journeyapps.com/
Apache License 2.0
5.74k stars 1.27k forks source link

Scan Position does not fit inside NestedScrollView #704

Open Robin1193 opened 2 years ago

Robin1193 commented 2 years ago

Description of the problem:

Dear Zxing-Android-Embedded-Team,

I'm using your QR-Code-Scanner to scan some QR-codes in some of our apps. If I use the QR-Code-Reader inside a fullscreen-view (without a NestedScrollView etc.) the QR-Code-Reader works just fine. But if i use the reader within a NestedScrollView the Scan Result-Point's does not match with the Camera Preview and the Scan-Region of the QR-Code does not fit with the Scan-Rectangle. (See Picture of my Test-App)

(The upper two yellow Points should match to the upper two Rectangles of the QR-Code and the botton-left should match to the botton Rectangle of the QR-Code).

In our productive app the result points are completly outside of the scan frame and only reacts if the qr-code is 2cm under the scan-frame.

Could you check why the qr-code-reader doesn't work correctly inside a NestedScollView?

Thank you for your help!

Robin

Picture 1: Screenshot_20220420-155135_TestZxingQrApp

Example-Code: main_fragment.xml `<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:zxing_barcode_view="http://schemas.android.com/apk/res-auto" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.main.MainFragment">

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <com.journeyapps.barcodescanner.DecoratedBarcodeView
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:id="@+id/barcodeView"
            zxing_barcode_view:zxing_framing_rect_width="150dp"
            zxing_barcode_view:zxing_framing_rect_height="150dp"
            />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:itemCount="50"
            android:nestedScrollingEnabled="false"
            />

    </androidx.appcompat.widget.LinearLayoutCompat>

</androidx.core.widget.NestedScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>`

MainFragment: ` class MainFragment : Fragment(), BarcodeCallback {

private val requestCameraPermissionLauncher =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        lifecycleScope.launch(Dispatchers.Main.immediate) {
            if (isGranted) {
                if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
                    startQrCodeReader()
                }
            } else {
                showSnackbar("Permission Denied")
            }
        }
    }

// This property is only valid between onCreateView and onDestroyView.
private var _binding: MainFragmentBinding? = null
private val binding get() = _binding!!

private val scannedQrCode = MutableSharedFlow<String?>()

private lateinit var adapter: TestRecyclerViewAdapter

companion object {
    fun newInstance() = MainFragment()
}

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    _binding = MainFragmentBinding.inflate(layoutInflater)
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    // Only used to show some fake-data
    adapter = TestRecyclerViewAdapter()

    binding.recyclerView.adapter = adapter
    binding.recyclerView.layoutManager = LinearLayoutManager(context ?: return)

    observeScannedQrCodes()
    receiveCameraPermission()
    initializeQrCodeReader()
}

override fun onResume() {
    super.onResume()
    startQrCodeReader()

    addTestDataIntoRecyclerView()
}

private fun addTestDataIntoRecyclerView() {
    val items = mutableListOf<String>()
    for(index in 0 until 50) {
        items.add("Text $index")
    }
    adapter.submitList(items)
}

override fun onPause() {
    super.onPause()
    stopQrCodeReader()
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

private fun observeScannedQrCodes() {
    lifecycleScope.launch(Dispatchers.Default) {
        scannedQrCode.collect { text ->
            // Process scanned QR-Code
            lifecycleScope.launch(Dispatchers.Main.immediate) {
                startQrCodeReader()
            }
        }
    }
}

private fun receiveCameraPermission() {
    if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA)
        != PackageManager.PERMISSION_GRANTED
    ) {
        requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA)
    }
}

private fun initializeQrCodeReader() {
    val formats = listOf(BarcodeFormat.QR_CODE)
    binding.barcodeView.decoderFactory = DefaultDecoderFactory(formats)
    binding.barcodeView.decodeSingle(this)
}

fun startQrCodeReader() {
    binding.barcodeView.resume()
    binding.barcodeView.decodeSingle(this)
}

fun stopQrCodeReader() {
    binding.barcodeView.pause()
}

override fun barcodeResult(result: BarcodeResult?) {
    GlobalScope.launch {
        scannedQrCode.emit(result?.text)
    }
}

}`

Which library version are you using? E.g. 3.2.0. 'com.journeyapps:zxing-android-embedded:4.3.0@aar' 'com.google.zxing:core:3.4.1'

Which phone/tablet are you using, and which Android version does it run? (e.g. Samsung Galaxy S5, Android 5.0) Samsung Galaxy A32 5G Samsung Galaxy Tab S4 and others

Does the same happen on other devices or an emulator? Device

Can you reproduce the issue in the sample project included with the library? If not, can you provide your own sample project or sample code that produces this error? See Code-Snippets

In the case of an error do you have a stack trace or adb logs? No

Robin1193 commented 2 years ago

Dear Zxing-Android-Embedded-Team,

is there still a solution for this problem?

Regards Robin