在我的RecyclerView适配器中,我的行包含显示日期的TextView。如果用户单击TextView,则会显示一个DialogFragment,允许用户选择时间和日期,然后通过界面传回Date。
但是我不知道如何在我添加到TextView的onClick方法中获取日期。
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?
}
});
答案 0 :(得分: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
}
以下是使用索引位置和Calendar
对象的DialogFragment示例:
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);
答案 1 :(得分:0)
尝试
RecyclerView.notifyItemChanged(i);
其中i是要更新的项目的索引。
答案 2 :(得分:0)
我想提出一个更简单的解决方案:由于单击处理程序将视图作为参数接收,因此可以使用视图上的标签来实现回收站适配器和选择器对话框之间的所有必要通信。在此处看到一个对话框序列,可以同时设置日期和时间:
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);
}
}