android - 在 DialogFragment 中附加时,Android 侦听器始终为空
问题描述
这里的高中老师试图教如何实现一个 DialogFragment 与侦听器附加一个接口到显示它的片段。由于某种原因,侦听器始终为空,当对话框显示时,当我按下对话框的确定或取消按钮时,向实现方法的转移不起作用,它停止了我调用侦听器类的行(始终为空)在 alertDialog.Builder 这是我的代码,谢谢
这是我调用对话框片段的片段
package net.ccl.monapp.ui;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import net.ccl.monapp.R;
public class AnimationFragment extends Fragment implements MonDialogFragment.MonDialogListener {
public AnimationFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_animation,container,false);
Button myButton = root.findViewById(R.id.bt_dialog);
final TextView tvTitre = root.findViewById(R.id.tv_titre);
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogFragment myDialog = new MonDialogFragment();
// Show Alert DialogFragment
myDialog.show(getFragmentManager(), "Dialog");
}
});
return root;
}
@Override
public void onDialogPositiveClick(DialogFragment dialog) {
TextView myTitre = getView().findViewById(R.id.tv_titre);
myTitre.setText("Mon nouveau titre");
dialog.dismiss();
}
@Override
public void onDialogNegativeClick(DialogFragment dialog) {
Toast.makeText(getActivity(),"Vous avez canceler l'action du dialog",Toast.LENGTH_SHORT);
}
}
这里是我的 DialogFragment
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
public class MonDialogFragment extends DialogFragment {
public MonDialogFragment() {
}
public interface MonDialogListener {
void onDialogPositiveClick(DialogFragment dialog);
void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
public MonDialogListener listener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
// Instantiate the NoticeDialogListener so we can send events to the host
listener = (MonDialogListener) context;
} catch (ClassCastException e) {
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Mon interface dialog");
builder.setMessage("Ceci est un message qui explique que tu peux changer le titre du fragment animation en cliquant sur ok");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
listener.onDialogPositiveClick(MonDialogFragment.this);
}
});
builder .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
listener.onDialogNegativeClick(MonDialogFragment.this);
}
});
return builder.create();
}
}
这里是我的 logcat
Process: net.ccl.monapp, PID: 13691
java.lang.NullPointerException: Attempt to invoke interface method 'void net.ccl.monapp.ui.MonDialogFragment$MonDialogListener.onDialogPositiveClick(androidx.fragment.app.DialogFragment)' on a null object reference
at net.ccl.monapp.ui.MonDialogFragment$1.onClick(MonDialogFragment.java:56)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
解决方案
你onAttach()
实际上并没有做任何事情,因为Context
你试图投射的是你的Activity
,而不是你的AnimationFragment
。
您AnimationFragment
应该通过覆盖在 Dialog 上设置侦听器,而不是伸手去接听您的听众onAttachFragment()
。
首先,您需要通过更改您的使用来确保您MonDialogFragment
是您的子片段:AnimationFragment
show()
getChildFragmentManager()
myDialog.show(getChildFragmentManager(), "Dialog");
然后,覆盖onAttachFragment()
你的AnimationFragment
:
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment instanceof MonDialogFragment) {
((MonDialogFragment) fragment).listener = this;
}
}
然后,您可以完全onAttach()
删除MonDialogFragment
。
推荐阅读
- kubernetes-helm - 我可以在脚本中使用 helm 图表中的变量吗?
- c# - HtmlAgilityPack - 如何在函数中获取 Innerhtml 值{}
- sql - 雪花案例语句 - 如果列中存在值,则返回 1,否则返回 0
- css - KendoWindow 不在移动/平板电脑上垂直居中
- flutter - 如何解决错误(查找已停用小部件的祖先是不安全的。)
- python - 如何在 mongodb 更改流中监听嵌套数组的特定字段的更改?
- python - python concurrent.futures.process.BrokenProcessPool
- c++ - 无法在 Visual Studio Code 中编译或运行 C++ 项目
- flutter - Flutter 错误 - 在构建期间调用了 setState() 或 markNeedsBuild()
- javascript - CSS 背景图像未完全填充 + JavaScript 错误处理程序