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");
}
这样就成功了。
我想从 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");
}
这样就成功了。