回调抛出NullPointerException(从适配器中分段)

时间:2015-07-06 13:02:00

标签: java android android-fragments callback android-alertdialog

我正在尝试从AlertDialog中获取信息。点击我的recyclerView中的删除按钮后,系统会询问用户是否确定。如果“是”,则应删除所选数据集。使用this tutorial我尝试实现回调以获取所需信息,但我总是得到NullPointerException。我无法弄清楚为什么。也许有人可以帮我一些意见吗?

AlertDialog:

public class deleteAlertFragment extends DialogFragment {
    private OnAddFriendListener callback;

    public interface OnAddFriendListener {
        public void onAddFriendSubmit(String friendEmail);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            callback = (OnAddFriendListener) getTargetFragment();
        } catch (ClassCastException e) {
            throw new ClassCastException(
                    "Calling Fragment must implement OnAddFriendListener");
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.frag_message)
                .setPositiveButton(R.string.frag_ok,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
//ERROR!
                                callback.onAddFriendSubmit("Kartoffel");

                            }
                        })
                .setNegativeButton(R.string.frag_abort,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // User cancelled the dialog
                            }
                        });
        // Create the AlertDialog object and return it
        return builder.create();
    }

}

ERROR:

07-06 12:11:44.517: E/AndroidRuntime(1325): FATAL EXCEPTION: main
07-06 12:11:44.517: E/AndroidRuntime(1325): Process: com.holg.prinoviskalkulator, PID: 1325
07-06 12:11:44.517: E/AndroidRuntime(1325): java.lang.NullPointerException: Attempt to invoke interface method 'void com.holg.prinoviskalkulator.deleteAlertFragment$OnAddFriendListener.onAddFriendSubmit(java.lang.String)' on a null object reference
07-06 12:11:44.517: E/AndroidRuntime(1325):     at com.holg.prinoviskalkulator.deleteAlertFragment$1.onClick(deleteAlertFragment.java:36)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at android.os.Handler.dispatchMessage(Handler.java:102)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at android.os.Looper.loop(Looper.java:135)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at android.app.ActivityThread.main(ActivityThread.java:5257)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at java.lang.reflect.Method.invoke(Native Method)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at java.lang.reflect.Method.invoke(Method.java:372)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
07-06 12:11:44.517: E/AndroidRuntime(1325):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

RecycleViewAdapter:

public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.PersonViewHolder> implements OnAddFriendListener{

    public static class PersonViewHolder extends RecyclerView.ViewHolder {

        CardView cv;
        TextView stintDate;
        TextView stintDuration;
        TextView stintStartTime;
        TextView stintWage;
        Button deleteButton;

        PersonViewHolder(View itemView) {
            super(itemView);
            cv = (CardView)itemView.findViewById(R.id.card_view);

            stintDate = (TextView)itemView.findViewById(R.id.txtDate);
            stintStartTime = (TextView)itemView.findViewById(R.id.txtStartTime);
            stintDuration = (TextView)itemView.findViewById(R.id.txtDuration);
            stintWage = (TextView)itemView.findViewById(R.id.txtWage);
            deleteButton = (Button) itemView.findViewById(R.id.back_delete);
        }
    }

    List<Stint> stints;
    Calendar cal;
    DatabaseHandler db;
    int y = 0;

    RecycleViewAdapter(DatabaseHandler db){
        this.stints = db.getAllStintsList();
        this.db = db;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_card_layout, viewGroup, false);
        PersonViewHolder pvh = new PersonViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(final PersonViewHolder personViewHolder, final int i) {

        cal = new GregorianCalendar(stints.get(i).year, stints.get(i).month, stints.get(i).day);
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy",Locale.GERMAN);

        personViewHolder.stintDate.setText(i+1 + ") " + sdf.format(cal.getTime()));
        personViewHolder.stintStartTime.setText("" + stints.get(i).startTime);
        personViewHolder.stintDuration.setText(stints.get(i).duration + " h");
        personViewHolder.stintWage.setText(String.format("%.2f €",stints.get(i).wage));

        personViewHolder.deleteButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {

                FragmentManager fm = ((Activity) v.getContext()).getFragmentManager();
                deleteAlertFragment dialog = new deleteAlertFragment();
                dialog.show(fm, "mydialog");

                if(y==1){

                db.deleteEntry(stints.get(i).id);
                stints.remove(i);
                notifyDataSetChanged();
                personViewHolder.getAdapterPosition();
                y=0;
                }
            }
        });   
    }

    @Override
    public void onAddFriendSubmit(String friendEmail) {
    y=1;    
    }

    @Override
    public int getItemCount() {
        return stints.size();
    }
}

2 个答案:

答案 0 :(得分:1)

您已经创建了变量callBack,但是您还没有创建它应该引用的对象。 尝试: private OnAddFriendListener callback = new OnAddFriendListener(); 或者无论对象的构造函数是什么。

希望它有所帮助。

答案 1 :(得分:0)

您可以更改DialogFragment以使用静态方法获取新实例,而不是调用new deleteAlertFragment(),然后通过该方法传递回调。例如,

@Override
public static deleteAlertFragment newInstance(OnAddFriendListener friendCallback) {
    deleteAlertFragment instance = new deleteAlertFragment();
    instance.callback = friendCallback;
    return instance;
}

如果您要使用onCreate方法,则应从deleteAlertFragment移除newInstance方法。

然后,在RecyclerViewAdapter课程中,您将使用deleteAlertFragment dialog = deleteAlertFragment.newInstance(RecyclerViewAdapter.this);

创建对话框

此外,您还应该在完成后将回调设置为null,以避免内存泄漏。您可以将此添加到您的班级deleteAlertFragment

@Override
public void onDestroy() {
    super.onDesroy();
    callback = null;
}

最后,在Java中,类名以大写字母开头是标准。因此,deleteAlertFragment应更改为DeleteAlertFragment,但这无论如何都不会影响您的代码。它只是提高可读性的常见做法。只有方法和变量应以小写字母开头。