1
I’m trying to implement an interface I created within a fragment, but I’m not succeeding. My fragment is being defined with the following code:
package fragments;
import pickers.DateTimePickerFragment;
import pickers.DateTimePickerFragment.DateTimeSetListener;
import singletons.SingletonUser;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import br.bytecode.tarefas.R;
import classes.Event;
import database.Database;
public class NewEventFragment extends Fragment implements DateTimeSetListener {
EditText name, place, date, contact;
public NewEventFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View rootView = inflater.inflate(R.layout.fragment_new, container,
false);
name = (EditText) rootView.findViewById(R.id.new_input_name);
place = (EditText) rootView.findViewById(R.id.new_input_place);
date = (EditText) rootView.findViewById(R.id.new_input_datetime);
contact = (EditText) rootView.findViewById(R.id.new_input_contact);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
date.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
DateTimePickerFragment dtp = new DateTimePickerFragment();
dtp.show(getFragmentManager(), "date_time_picker");
return false;
}
});
super.onActivityCreated(savedInstanceState);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_newevent, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.menu_newevent_save:
Event event = new Event();
event.setUserId(SingletonUser.getInstance().getId());
event.setName(name.getText().toString());
event.setPlace(place.getText().toString());
event.setDate(date.getText().toString());
event.setContact(contact.getText().toString());
Database db = new Database(getActivity());
db.addEvent(event);
Toast.makeText(getActivity(), "Evento criado com sucesso.",
Toast.LENGTH_SHORT).show();
getActivity().finish();
case R.id.menu_newevent_discard:
getActivity().finish();
// getActivity().getFragmentManager().popBackStack();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onDateTimeSet(int dia, int mes, int ano, int hora, int minuto) {
}
}
Note in the class declaration of fragment that it implements the interface I need. However, when running the program, I get the following error:
06-23 10:57:04.698: E/AndroidRuntime(18295): FATAL EXCEPTION: main
06-23 10:57:04.698: E/AndroidRuntime(18295): Process: br.bytecode.tarefas, PID: 18295
06-23 10:57:04.698: E/AndroidRuntime(18295): java.lang.ClassCastException: activities.ManagementActivity@424699e8 deve implementar DateTimeSetListener
06-23 10:57:04.698: E/AndroidRuntime(18295): at pickers.DateTimePickerFragment.onAttach(DateTimePickerFragment.java:42)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:849)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.app.BackStackRecord.run(BackStackRecord.java:684)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.os.Handler.handleCallback(Handler.java:733)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.os.Handler.dispatchMessage(Handler.java:95)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.os.Looper.loop(Looper.java:136)
06-23 10:57:04.698: E/AndroidRuntime(18295): at android.app.ActivityThread.main(ActivityThread.java:5086)
06-23 10:57:04.698: E/AndroidRuntime(18295): at java.lang.reflect.Method.invokeNative(Native Method)
06-23 10:57:04.698: E/AndroidRuntime(18295): at java.lang.reflect.Method.invoke(Method.java:515)
06-23 10:57:04.698: E/AndroidRuntime(18295): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
06-23 10:57:04.698: E/AndroidRuntime(18295): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
06-23 10:57:04.698: E/AndroidRuntime(18295): at dalvik.system.NativeStart.main(Native Method)
It is as if the interface had not been implemented at any time within the fragment, because the mistake happens inside the Activity that contains it. Is there any solution to this? How can I make Android understand that the interface is in fragment and not in the Activity? The class that needs an interface is this:
package pickers;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.text.format.Time;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.TimePicker;
import android.widget.TimePicker.OnTimeChangedListener;
import br.bytecode.tarefas.R;
public class DateTimePickerFragment extends DialogFragment {
Time now = new Time();
private int dia, mes, ano, hora, minuto;
private DateTimeSetListener mListener;
boolean changedTime = false, changedDate = false;
public DateTimePickerFragment() {
}
public interface DateTimeSetListener {
public void onDateTimeSet(int dia, int mes, int ano, int hora,
int minuto);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (DateTimeSetListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " deve implementar DateTimeSetListener");
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View rootView = inflater.inflate(R.layout.date_time_picker, null);
TimePicker tPicker = (TimePicker) rootView
.findViewById(R.id.timePicker1);
DatePicker dPicker = (DatePicker) rootView
.findViewById(R.id.datePicker1);
now.setToNow();
dPicker.init(now.year, now.month, now.monthDay,
new OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
changedDate = true;
ano = year;
mes = monthOfYear;
dia = dayOfMonth;
}
});
tPicker.setIs24HourView(true);
tPicker.setOnTimeChangedListener(new OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
changedTime = true;
hora = hourOfDay;
minuto = minute;
}
});
builder.setView(rootView);
builder.setTitle("Escolher data e hora");
builder.setPositiveButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
if (mListener != null) {
if (changedTime == false) {
hora = now.hour;
minuto = now.minute;
}
if (changedDate == false) {
dia = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
mes = Calendar.getInstance().get(Calendar.MONTH);
ano = Calendar.getInstance().get(Calendar.YEAR);
}
mListener.onDateTimeSet(dia, mes, ano, hora, minuto);
}
}
});
builder.setNegativeButton("Cancelar", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
return builder.create();
}
}
Thank you very much, I preferred to use a Setter, I found it simpler.
– Renan Lazarotto