我尝试将一个Java文件转换为Kotlin文件时,遇到了来自构造函数参数var view: View
的问题。我遇到过类似的问题,但还没有遇到过使用对话框的问题。将视图作为承包商参数传递是很重要的,因为我使用该视图实现一个依赖于对话框行为的重要功能。
转换为Kotlin之前
ackage com.indupendo.landing.ui.dialogs;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.indupendo.R;
import com.indupendo.databinding.DialogLoginBinding;
import com.indupendo.globals.utilities.Utils;
public class LoginDialog extends DialogFragment {
DialogLoginBinding binding;
View view;
public LoginDialog(View view) {
this.view = view;
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
binding = DialogLoginBinding.inflate(getLayoutInflater());
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(requireActivity(),
R.style.MaterialAlertDialog_rounded);
dialogBuilder.setView(binding.getRoot());
dialogBuilder.setNegativeButton("Cancel", (dialog, which) -> {
Utils.INSTANCE.showLoginCancellationSnackBar(view, getLayoutInflater());
dialog.cancel();
});
dialogBuilder.setPositiveButton("Login", (dialog, which) -> Toast.makeText(
getActivity(),
"Logged In",
Toast.LENGTH_LONG).show());
return dialogBuilder.create();
}
@Override
public void onCancel(@NonNull DialogInterface dialog) {
super.onCancel(dialog);
Utils.INSTANCE.showLoginCancellationSnackBar(view, getLayoutInflater());
dialog.cancel();
}
}
转换后
package com.indupendo.landing.ui.fragments
import android.app.Dialog
import com.indupendo.globals.utilities.Utils.showLoginCancellationSnackBar
import android.os.Bundle
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.indupendo.R
import android.content.DialogInterface
import android.view.View
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import com.indupendo.databinding.DialogLoginBinding
class LoginDialog(var view: View) : DialogFragment() {
var binding: DialogLoginBinding? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
binding = DialogLoginBinding.inflate(layoutInflater)
val dialogBuilder = MaterialAlertDialogBuilder(
requireActivity(),
R.style.MaterialAlertDialog_rounded
)
dialogBuilder.setView(binding!!.getRoot())
dialogBuilder.setNegativeButton("Cancel") { dialog: DialogInterface, which: Int ->
showLoginCancellationSnackBar(
view, layoutInflater
)
dialog.cancel()
}
dialogBuilder.setPositiveButton("Login") { dialog: DialogInterface?, which: Int ->
Toast.makeText(
activity,
"Logged In",
Toast.LENGTH_LONG
).show()
}
return dialogBuilder.create()
}
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
showLoginCancellationSnackBar(view, layoutInflater)
dialog.cancel()
}
}
我怎样才能重写Kotlin类并获得相同的结果而不出现这个bug呢?
2条答案
按热度按时间yqyhoc1h1#
当您使用具有如下属性的构造函数时
Kotlin正在尝试为它们创建getter和setter,它们的名字是
getPropertyName()
和setPropertyName()
。在您的示例中,getter getView()与您的一个基类(www.example.com)中的方法冲突Fragment.java:
您有几种方法可以修复此错误:
1.只需更改属性名称
1.将属性初始化替换为简单参数并手动初始化属性
1.用
@JvmField
注解来注解你的属性。这将指示Kotlin编译器不为这个属性生成getter/setter,并将它公开为一个字段有点跑题了:
虽然上面的选项可以解决这个错误,但是这个类还有一个更大的问题--向Fragment构造函数发送一个参数是一个相当危险的决定。
Fragment的所有子类都必须包含一个公共的无参数构造函数。框架经常会在需要的时候重新示例化一个fragment类,特别是在状态恢复的时候,并且需要能够找到这个构造函数来示例化它。如果无参数构造函数不可用,在状态恢复的某些情况下会发生运行时异常。
您可以关注此thread了解更多详细信息
ne5o7dgx2#
我考虑了@DmitryArc上面的回答,并想到了一个更安全的解决方案,遵循他们的**PS:“Fragment的所有子类都必须包含一个公共的无参数构造函数。"**不必传递构造函数参数,一种解决方法是必须通过
requireActivity()
函数和findViewById(...)
访问托管Activity的视图,在我的示例中是一个按钮。PS:欢迎任何人改进这个答案!