Как выполнить это обновление даты в моих строках RecyclerView?
В моем адаптере RecyclerView у моих строк есть TextViews, которые отображают даты. Если пользователь щелкает TextView, отображается DialogFragment, который позволяет пользователю выбрать время и дату, а затем Date передается обратно через интерфейс.
Однако я не знаю, как получить дату назад в методе onClick, который я добавил в свой TextView.
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
public TextView dateTextView;
public RecyclerViewHolder(View itemView) {
super(itemView);
dateTextView = (TextView) itemView.findViewById(R.id.date_textview);
dateTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//I can call my DialogFragment here but then what?
}
});
2 ответа
Вы можете создать интерфейс для связи с адаптером:
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
public TextView dateTextView;
private IAdapter adapter;
public RecyclerViewHolder(View itemView, IAdapter adapter) {
super(itemView);
dateTextView = (TextView) itemView.findViewById(R.id.date_textview);
this.adapter = adapter;
dateTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyDialogFragment fragment = MyDialogFragment.newInstance(getAdapterPosition(), adapter);
FragmentTransaction ft = v.getContext().getFragmentManager().beginTransaction();
fragment.show(ft, "calendarDialog");
}
});
}
}
Интерфейс, который должен реализовать адаптер:
interface IAdapter extends Serializable {
void setDataAt(int index, Calendar date);
void notifyItemChanged(int index);
}
Так как адаптер уже имеет notifyItemChanged
метод, вам нужно будет только реализовать setDataAt
метод.
Предполагая, что ваш адаптер будет содержать только даты, вот пример:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> implements IAdapter {
private List<Calendar> dates = new ArrayList<>();
public RecyclerViewAdapter(List<Calendar> dates) {
this.dates = dates;
}
@Override
public void setDataAt(int index, Calendar date) {
dates.add(index, date);
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View holderView = inflater.inflate(R.layout.view_holder, parent, false);
return new RecyclerViewHolder(holderView, this); // notice how we pass this adapter's interface along with the view
}
// Include other methods (getItemCount, onBindViewHolder, etc.)
// Adapter already has the notifyItemChanged(int index) method so no need to override it
}
Вот пример DialogFragment, который использует позицию индекса и Calendar
объект:
public static class MyDialogFragment extends DialogFragment {
private int index;
private IAdapter adapter;
public static MyDialogFragment newInstance(int index, IAdapter adapter) {
MyDialogFragment f = new MyDialogFragment();
Bundle args = new Bundle();
args.putInt("index", index);
args.putSerializable("adapter", adapter);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
index = args.getInt("index");
adapter = args.getSerializable("adapter");
}
// Build view and set OnClickListener for setting date
}
После того, как пользователь обновит дату, вызовите следующее:
adapter.setDataAt(index, date);
adapter.notifyItemChanged(index);
Я хотел бы предложить более простое решение: поскольку обработчик кликов принимает представление как параметр, вся необходимая связь между адаптером ресайклера и диалоговыми окнами средства выбора может быть достигнута с помощью тегов в представлении. Смотрите здесь последовательность диалогов, которая позволяет установить дату и время:
RecyclerAdapter (предположим, что встречающийся список массивов - это модель данных):
@Override
public void onBindViewHolder(
EncounterViewHolder holder, int position) {
final Encounter encounter = encounters.get(position);
holder.getDate().setText(encounter.getDate());
holder.getDate().setTag(R.string.tag_adapter, this);
holder.getDate().setTag(R.string.tag_position, new Integer(position));
holder.getDate().setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
showDatePickerDialog(view);
return true;
}
});
}
public void showDatePickerDialog(View view) {
DatePickerFragment datePickerFragment = new DatePickerFragment(view);
datePickerFragment.show(((FragmentActivity) context).getSupportFragmentManager(), "datePicker");
}
public void showTimePickerDialog(View view) {
TimePickerFragment timePickerFragment = new TimePickerFragment(view);
timePickerFragment.show(((FragmentActivity) context).getSupportFragmentManager(), "timePicker");
}
void notifyDateTimeChanged(int position, Calendar calendar) {
encounters.get(position).setDate(new Timestamp().get(calendar));
notifyDataSetChanged();
}
DatePickerFragment:
public class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
private View view;
DatePickerFragment(View view) {
this.view = view;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), this, year, month, day);
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
Calendar calendar = new GregorianCalendar();
calendar.set(year, month, day);
(this.view).setTag(R.string.tag_calendar, calendar);
EncounterRecyclerAdapter adapter = (EncounterRecyclerAdapter) (this.view).getTag(R.string.tag_adapter);
adapter.showTimePickerDialog(this.view);
}
}
TimePickerFragment:
public class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener {
private View view;
TimePickerFragment(View view)
{
this.view = view;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
return new TimePickerDialog(getActivity(), this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
EncounterRecyclerAdapter adapter = (EncounterRecyclerAdapter) (this.view).getTag(R.string.tag_adapter);
int position = ((Integer) (this.view).getTag(R.string.tag_position));
GregorianCalendar calendar = ((GregorianCalendar) (this.view).getTag(R.string.tag_calendar));
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), hour, minute);
adapter.notifyDateTimeChanged(position, calendar);
}
}
Пытаться
RecyclerView.notifyItemChanged(i);
где я - индекс элемента, который будет обновлен.