【问题标题】:Type Mismatched on Fragment片段上的类型不匹配
【发布时间】:2020-10-13 05:23:21
【问题描述】:

我正在开发使用 Zxing 扫描片段上的二维码的 Android 应用程序,为了实现这一点,我按照本教程获得了所需的结果。Link I Followed to Scan QR on Fragment

我用来在**QRCodeFragment ** Fragment 上扫描二维码的代码看起来

class QRCodeFragment : Fragment() {

internal var txtName: TextView? = null
internal var txtSiteName: TextView? = null
internal var btnScan: Button? = null
internal var qrScanIntegrator: IntentIntegrator? = null


override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return inflater?.inflate(R.layout.fragment_qr_code, container, false)
}


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

    txtName = view.findViewById(R.id.name)
    txtSiteName = view.findViewById(R.id.site_name)

    btnScan = view.findViewById(R.id.btnScan)
    btnScan!!.setOnClickListener { performAction() }

    qrScanIntegrator = IntentIntegrator.forFragment(this)
    qrScanIntegrator?.setOrientationLocked(false)

    // Different Customization option...
    qrScanIntegrator?.setPrompt(getString(R.string.scan_a_code))
    qrScanIntegrator?.setCameraId(0)  // Use a specific camera of the device
    qrScanIntegrator?.setBeepEnabled(false)
    qrScanIntegrator?.setBarcodeImageEnabled(true)

    super.onViewCreated(view, savedInstanceState)
}

private fun performAction() {
    qrScanIntegrator?.initiateScan()
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
    if (result != null) {
        // If QRCode has no data.
        if (result.contents == null) {
            Toast.makeText(activity, R.string.result_not_found, Toast.LENGTH_LONG).show()
        } else {
            // If QRCode contains data.
            try {
                // Converting the data to json format
                val obj = JSONObject(result.contents)
                // Show values in UI.
                txtName?.text = obj.getString("name")
                txtSiteName?.text = obj.getString("site_name")

            } catch (e: JSONException) {
                e.printStackTrace()

                // Data not in the expected format. So, whole object as toast message.
                Toast.makeText(activity, result.contents, Toast.LENGTH_LONG).show()
            }

        }
    } else {
        super.onActivityResult(requestCode, resultCode, data)
    }
}

}

从我调用片段的主要活动就像

    private fun ShowQRCodeFragment() {
    val newFragment = QRCodeFragment()
    val transaction1: FragmentTransaction = supportFragmentManager.beginTransaction();
    transaction1.replace(R.id.frameLayout, newFragment);
    transaction1.addToBackStack(null);
    transaction1.commit();
}

在主片段中它显示类型不匹配,我指出它转到正在扩展的片段名称 Fragment()

 public Fragment() {
    initLifecycle();
}

错误图像看起来

如果我更改它,它会在活动中显示错误,从我调用扫描 QR 片段的位置

【问题讨论】:

  • 尝试找出提供和请求类的全名(包括包)。一个可能来自 AndroidX 或支持库,另一个来自主 API。

标签: android kotlin android-fragments fragment android-fragmentactivity


【解决方案1】:

您的QRCodeFragment 类正在扩展Fragment,哪个? (检查文件顶部的imports)

我们有 android.app.Fragmentandroidx.fragment.app.Fragment - 根据您的方法选择合适的

内置android.app.Fragment 目前已弃用,您应该使用androidx 版本,但有可能某些库仍然需要原始版本(遗憾)

【讨论】:

  • 检查您的方法需要哪个Fragment,例如forFragment。按住 ctrl/cmd 按钮并单击它,将打开带有类的选项卡,然后在里面按住 ctrl/cmd 并将光标移动到 Fragment 类上,这是您的方法的参数 - 您将看到所需的完整包 Fragment。除此之外,就像其他建议一样:super.onViewCreated 应该是您覆盖方法中的第一个调用,但我仍然认为这不会导致您的问题...
  • 可能是其他方法:尝试将 QRCodeFragment : Fragment 替换为 QRCodeFragment : android.app.FragmentQRCodeFragment : androidx.fragment.app.Fragment - 每次更改后进行干净构建(Android Studio -> 构建 -> 重建项目)
  • @Dev Bhattacharjee - 你能解释一下为什么这个改变应该解决问题吗?它是说类型不匹配并且移​​动某些行肯定不会改变类型......
  • 由于 QRCodeFragment 是扩展 Fragment 类 并且 Fragment 实现 需要调用基类函数.. this 在他的例子中是指基类 Fragment 而不是 QRCodeFragment。为了解决这个问题,他需要先调用 super.onViewCreated。
  • 恕我直言:Usman 有两个问题,一个是类不匹配(由发布的异常指出),我的回答帮助了他。并且您发现了另一个问题并用错位线回答了潜在的“未来”问题。我们的两个帖子都有帮助,但我的帖子仍然在回答已发布的问题并且您得到了支持,因为它也很有帮助,并且“终于”使他的代码工作
【解决方案2】:

我认为是因为你的进口

您需要将导入从 android.support.v4.app.Fragment 更改为 android.app.Fragment,反之亦然

【讨论】:

  • 我已经改变了这个,但之后从我调用片段的地方,输入不匹配的错误去那里
【解决方案3】:

如果您的QRCodeFragment 扩展了androidx.fragment.app.Fragment,那么您应该使用IntentIntegrator.forSupportFragment

【讨论】:

  • import android.support.v4.app.Fragment 添加此问题后问题保持不变。
  • 在哪里使用 IntentIntegrator.forSupportFragment,在导入时?
  • @UsmanAli 不要使用android.support.v4.app.Fragment,它已被弃用,请改用androidx.fragment.app.FragmentIntentIntegrator.forSupportFragment
  • 但是当我扩展 Fragment 时它不显示 androidx.fragment.app.Fragment 它只显示 v4 和应用程序片段
  • 你可以使用“just”Fragment,因为你有一些 import 这个类。如果您有import android.support.v4.app.Fragment,那么您应该迁移到AndroidX 库并使用androidx.fragment.app.FragmentMigrating to AndroidX
【解决方案4】:

在 onViewCreated 中,您首先要做自己的事情,然后调用 super.onViewCreated

this 指的是 Base Fragment 实例,当您的代码在 super 调用之前进行时,它假定您的 Fragment 类型Fragment 而不是 QRCodeFragment 解决这个问题

First call super.onViewCreated in onViewCreated and then do your code part

这样做-

override fun onViewCreated(view:View, savedInstanceState:Bundle? ) 
{
 super.onViewCreated(view, savedInstanceState) 
//your code part
} 

【讨论】:

  • 我是反对者,对于迟到的答案感到抱歉:因为其他答案已经表明真正的问题是 Fragment 类来自主 API,而应该来自兼容性库反而。如果预期主 API 中的 Fragment 是预期的,那么如果提供了类似 QRCodeFragment 的派生类对象,则不会导致此类错误,因为至少在编译时使用派生类总是正确的对象而不是基类对象作为参数。您建议的呼叫重新排序无助于解决最初的问题。
  • 这不是兼容性问题。你应该先看看这个人问了什么。这不仅仅是通过函数调用重新排序。需要重新排序,因为首先需要对 超类方法调用QRFragment 类继承了Fragment 类和some methods from Fragment class were overridden。结果this 指的是Fragment 而不是QRFragment 类,这就是the type mismatch was shown 的原因。当用户完全按照我说的做时,问题就解决了。
  • 重新排序可能会解决可能的运行时问题,但编译时类型不匹配不可能是由错误的顺序引起的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多