DialogFragment 在 Attach 上抛出 ClassCastException

DialogFragment is throwing ClassCastException onAttach

我想从 SQLite 数据库更新现有数据,为此我做了一个 class UpdateData,但是当附加数据时它抛出 ClassCastException。我几乎到了那里一切都出错的地方。但是不知道要修复什么

这是日志

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.recyclerviewwithsqlite, PID: 2257
    java.lang.ClassCastException: com.example.recyclerviewwithsqlite.MainActivity@2d3a0725
        at com.example.recyclerviewwithsqlite.UpdateData.onAttach(UpdateData.java:52)
        at androidx.fragment.app.Fragment.performAttach(Fragment.java:2922)
        at androidx.fragment.app.FragmentStateManager.attach(FragmentStateManager.java:464)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:275)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
        at androidx.fragment.app.FragmentManager.run(FragmentManager.java:524)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

这是我的代码 UpdateData.java



import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDialogFragment;

public class UpdateData extends AppCompatDialogFragment {
    private Data listener;
    @Override
    public Dialog onCreateDialog(Bundle savedInstances) {
        AlertDialog.Builder builder= new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.update_data,null);
        EditText name = view.findViewById(R.id.update_name);
        EditText salary = view.findViewById(R.id.update_salary);
        Bundle bundle = listener.ReceiveData();
        String n = bundle.getString("name");
        double s = bundle.getDouble("salary");

        name.setText(n);
        salary.setText(Double.toString(s));
        builder.setView(view)
                .setTitle("Update Data")
                .setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .setPositiveButton("Add", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
        return builder.create();
    }

    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            listener = (Data) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString());
        }
    }

    public interface Data {
        Bundle ReceiveData();
    }
}

这里是EmployeeAdapter.java

package com.example.recyclerviewwithsqlite;

import android.content.Context;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class EmployeeAdapter extends RecyclerView.Adapter<EmployeeAdapter.ViewHolder> {
    private List<Employee> employeeList;
    private int position;
    FragmentManager fragmentManager;
    public EmployeeAdapter(List<Employee> employeeList, FragmentManager fragmentManager) {
        this.employeeList = employeeList;
        this.fragmentManager = fragmentManager;
    }

    @Override
    public EmployeeAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        View employeeView = inflater.inflate(R.layout.list_item_view,parent,false);

        ViewHolder viewHolder = new ViewHolder(employeeView);
        return viewHolder;
    }


    void setPosition(int position) {
        this.position = position;
    }
    @Override
    public void onBindViewHolder(EmployeeAdapter.ViewHolder holder, int position) {
        Employee employee = employeeList.get(position);
        TextView name = holder.name;
        TextView salary = holder.salary;
        name.setText(employee.getName());
        salary.setText(Double.toString(employee.getSalary()));
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                setPosition(holder.getPosition());
                return false;
            }
        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener,UpdateData.Data {
        public TextView name;
        public TextView salary;

        public ViewHolder(View itemView) {
            super(itemView);

            name = itemView.findViewById(R.id.name_text_view);
            salary = itemView.findViewById(R.id.salary_text_view);
            itemView.setOnCreateContextMenuListener(this);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    UpdateData updateData = new UpdateData();
                    updateData.show(fragmentManager,"Update Data");
                }
            });
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            MenuItem edit = menu.add(0, R.id.edit, 0, "Edit");
            MenuItem delete = menu.add(0, R.id.delete, 1, "Delete");
            edit.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {

                    return true;
                }
            });
            delete.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    Data listener;
                    try {
                        listener = (Data) v.getContext();
                        listener.deleteData(position);
                    } catch (ClassCastException ex) {
                        throw new ClassCastException(v.getContext().toString());
                    }

                    return true;
                }
            });

        }

        @Override
        public Bundle ReceiveData() {
            Bundle bundle = new Bundle();
            bundle.putString("name",employeeList.get(position).getName());
            bundle.putDouble("salary",employeeList.get(position).getSalary());
            return bundle;
        }
    }

    public interface Data {
        public void deleteData(int position);
    }
}

EmployeeAdapter.java 中的 FragmentManager 来自 MainActivity.java 使用函数 getSupportFragmentManager()。我想那是我做错事的地方。那我应该做些什么改变才能让它发挥作用。

我终于通过将 onAttach 方法替换为 setListener 的方法来做到了。 以下是代码

package com.example.recyclerviewwithsqlite;


import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDialogFragment;

public class UpdateData extends AppCompatDialogFragment {
    DataListener dataListener;

    public Dialog onCreateDialog(Bundle savedInstances) {
        AlertDialog.Builder builder= new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.update_data,null);
        EditText name = view.findViewById(R.id.update_name);
        EditText salary = view.findViewById(R.id.update_salary);
        Bundle bundle = dataListener.ReceiveData();
        String n = bundle.getString("name");
        double s = bundle.getDouble("salary");

        name.setText(n);
        salary.setText(Double.toString(s));
        builder.setView(view)
                .setTitle("Update Data")
                .setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .setPositiveButton("Add", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
        return builder.create();
    }

    public void setDataListener(DataListener dataListener) {
        this.dataListener = dataListener;
    }

    public interface DataListener {
        Bundle ReceiveData();
    }
}

在此代码中,方法 setDataListener(DataListener dataListener) 允许我创建 dataListener 的实例,然后将其传递给 DialogFragment

然后在适配器中实现为

UpdateData updateData = new UpdateData();
    UpdateData.DataListener dataListener = new UpdateData.DataListener() {
        @Override
        public Bundle ReceiveData() {
            Bundle bundle = new Bundle();
            bundle.putString("name",employeeList.get(position).getName());
            bundle.putDouble("salary",employeeList.get(position).getSalary());
            return bundle;
        }

    };
    updateData.setDataListener(dataListener);
    updateData.show(fragmentManager,"Update Data");

}

这样就成功了。