如何对我的 RecyclerView 行执行此日期更新?

How to perform this date update on my RecyclerView rows?

在我的 RecyclerView 适配器中,我的行有显示日期的 TextView。如果用户单击 TextView,将显示一个 DialogFragment,让用户选择时间和日期,然后通过接口传回一个日期。

但是我不知道如何在我添加到我的 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?
                }
            });

尝试

RecyclerView.notifyItemChanged(i);

其中 i 是要更新的项目的索引。

您可以创建一个接口来与适配器通信:

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);
}

由于adapter已经有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);

我想提出一个更简单的解决方案:由于点击处理程序接收视图作为参数,回收器适配器和选择器对话框之间的所有必要通信都可以通过视图上的标签来实现。在此处查看允许设置日期和时间的对话框序列:

RecyclerAdapter(假设数组列表encounters为数据模型):

@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);
}
}