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