I want to update the existing data from SQLite database and for this purpose I made a class UpdateData but when the data is getting attached it is throwing ClassCastException. I almost got there where everything is going wrong. But don't know what to fix
Here is the Log
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$5.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)
Here is my code of
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();
}
}
Here is 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);
}
}
The FragmentManager
in EmployeeAdapter.java
is from MainActivity.java
using the function getSupportFragmentManager()
. I guess that is the part where I'm doing things wrong. Then what changes should I made to make it work.
I finally did it by replacing onAttach method with setListener's method. Following is the code
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();
}
}
In this code, the method setDataListener(DataListener dataListener)
is allowed me to create an instance of dataListener
and then pass it to DialogFragment
Then in the adapter it is implemented as
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");
}
In this way it worked successfully.