FirebaseRecyclerAdapter с динамическим запросом от обратного вызова фрагмента - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть действие, которое отображает список в RecyclerView, используя FirebaseRecyclerAdapter. Запрос должен быть динамическим - мне нужно прикрепить дату к концу. Поэтому я установил DatePicker DialogFragment. У dialogfragment есть интерфейс, который внедряется в упражнение для получения даты обратно от DatePicker. Дата возвращается хорошо. Проблема в том, что когда я подключаю новый адаптер к RecyclerView, код адаптера никогда не запускается. После обхода с помощью отладчика, дата возвращается к действию, затем код заканчивается во фрагменте, и адаптер никогда не присоединяется повторно. Так что у меня остался пустой экран вместо списка данных.

Активность:

public class DailyScheduleActivity extends AppCompatActivity implements
    HourlyTaskDialogFragment.HourlyTaskDialogListener,
    DatePickerFragment.OnFragmentInteractionListener {

private DatabaseReference mDatabase;
private RecyclerView mProtocolRv;
private String protocolKey;
private LocalDate chosenDate;
private ProtocolRecyclerViewAdapter mProtocolAdapter;
private String path;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_daily_schedule);

    if (chosenDate == null) {
        chosenDate = new LocalDate();
    }

    protocolKey = "daily/" + FirebaseAuth.getInstance().getCurrentUser().getUid() + "_";
    path = protocolKey + chosenDate;
    mDatabase = FirebaseDatabase.getInstance().getReference();

    Query query = mDatabase.child(path);

    FirebaseRecyclerOptions<Hour> options =
            new FirebaseRecyclerOptions.Builder<Hour>()
                    .setQuery(query, Hour.class)
                    .build();

    mProtocolRv = findViewById(R.id.rv_protocol);
    mProtocolRv.setHasFixedSize(false);
    LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
    mProtocolRv.setLayoutManager(mLayoutManager);
    mProtocolAdapter = new ProtocolRecyclerViewAdapter(this, mDatabase, path, options);
    mProtocolRv.setAdapter(mProtocolAdapter);
}

//####################################################################
//#### This is what runs after the date has been chosen.  When this is
//#### finished, the dialogfragment finishes running.  When control 
//#### returns to the activity, the adapter never loads the data.
//####################################################################
@Override
public void onFragmentInteraction(String date) {

    chosenDate = new LocalDate(date);
    path = protocolKey + chosenDate;
    Query query = mDatabase.child(path);

    FirebaseRecyclerOptions<Hour> options =
            new FirebaseRecyclerOptions.Builder<Hour>()
                    .setQuery(query, Hour.class)
                    .build();
    final FirebaseRecyclerAdapter oldAdapter = (FirebaseRecyclerAdapter) mProtocolRv.getAdapter();
    mProtocolAdapter = new ProtocolRecyclerViewAdapter(this, mDatabase, path, options);
    mProtocolRv.setAdapter(mProtocolAdapter);
    mProtocolAdapter.notifyDataSetChanged();
    if (oldAdapter != null) {
        //oldAdapter.cleanup(); - This can't run here because cleanup is not public so not sure what to do with it!
    }
}

public static class ProtocolRecyclerViewAdapter extends FirebaseRecyclerAdapter<Hour, ProtocolRecyclerViewAdapter.HourHolder> {

    private final DailyScheduleActivity mParentActivity;
    private DatabaseReference mDb;
    private String protocolUserDateKey;
    ProtocolNonMalignant mProtocol = new ProtocolNonMalignant();


    ProtocolRecyclerViewAdapter(DailyScheduleActivity parent, DatabaseReference db, String path, FirebaseRecyclerOptions<Hour> options) {
        super(options);
        mParentActivity = parent;
        mDb = db;
        protocolUserDateKey = path;
    }

    @Override
    public void onDataChanged() {
        super.onDataChanged();

    }

    @NonNull
    @Override
    public HourHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_protocol_row, parent, false);
        return new HourHolder(view);
    }

    @Override
    public void onBindViewHolder(final @NonNull HourHolder holder, final int position, final Hour currentHour) {

        holder.mHourCheckBox.setText(currentHour.toString() + protocolUserDateKey);

    }

    class HourHolder extends RecyclerView.ViewHolder {

        final IndeterminateCheckBox mHourCheckBox;
        final ImageView mOpenTasks;
        final TextView mHour;

        HourHolder(View view) {
            super(view);
            mHourCheckBox = (IndeterminateCheckBox) view.findViewById(R.id.cb_hour_all);
            mOpenTasks = (ImageView) view.findViewById(R.id.open_tasks);
            mHour = (TextView) view.findViewById(R.id.hour);
        }
    }

}

@Override
protected void onStart() {
    super.onStart();
    mProtocolAdapter.startListening();
}

@Override
protected void onStop() {
    super.onStop();
    mProtocolAdapter.stopListening();
}

}

Datepicker DialogFragment:

public class DatePickerFragment extends DialogFragment {

private OnFragmentInteractionListener mListener;
private String chosenDate;

public DatePickerFragment() {}

public Dialog onCreateDialog(Bundle savedInstanceState) {

    final Calendar c = Calendar.getInstance();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);

    return new DatePickerDialog(getActivity(), dateSetListener, year, month, day);
}

private DatePickerDialog.OnDateSetListener dateSetListener =
    new DatePickerDialog.OnDateSetListener() {
        public void onDateSet(DatePicker view, int year, int month, int day) {
            chosenDate = view.getYear() + "-" + (view.getMonth()+1) + "-" + view.getDayOfMonth();
            if (mListener != null) {
                mListener.onFragmentInteraction(chosenDate);
            }
        }
    };


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_date_picker, container, false);
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

public interface OnFragmentInteractionListener {
    void onFragmentInteraction(String date);
}

}

...