我有一个FirebaseRecyclerAdapter显示对象及其状态的列表。
我单击右侧的箭头,然后打开一个AlertDialog片段,可以在其中更改每个项目的状态(选中/取消选中该项目)。
通过实现DialogFragment的接口,将AlertDialog片段的结果发送回包含recyclerview的活动:
@Override
public void onDialogPositiveClick(Bundle bundle) {
Hour hour = bundle.getParcelable("hour");
mDatabase.child(protocolKey).child(String.valueOf(hour.getMilitaryHour())).setValue(hour);
mProtocolAdapter.notifyDataSetChanged();
}
从Dialog片段返回的数据是正确的-onDialogPositiveClick中的小时对象确实显示了正确的数据以及在DIALOGFRAGMENT中所做的更新。并且数据库中的数据条目已正确更新。但是,notifyDataSetChanged不能正确更新列表及其状态。
我在项目的另一部分也遇到了类似的问题(当前被剥离以隔离当前问题),结果是由于使用侦听器和回收视图而造成的。我猜这是一个类似的实例,但是该解决方案(首先将侦听器设置为null)在这里不起作用。
使用Recyclerview进行的活动:
public class DailyScheduleActivity2 extends AppCompatActivity implements HourlyTaskDialogFragment.HourlyTaskDialogListener {
private DatabaseReference mDatabase;
private RecyclerView mProtocolRv;
private String protocolKey;
private ProtocolRecyclerViewAdapter mProtocolAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_daily_schedule);
protocolKey = "daily/" + FirebaseAuth.getInstance().getCurrentUser().getUid() + "_" + new LocalDate();
mDatabase = FirebaseDatabase.getInstance().getReference();
Query query = mDatabase.child(protocolKey);
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, protocolKey, options);
mProtocolRv.setAdapter(mProtocolAdapter);
}
public static class ProtocolRecyclerViewAdapter extends FirebaseRecyclerAdapter<Hour, ProtocolRecyclerViewAdapter.HourHolder> {
private final DailyScheduleActivity2 mParentActivity;
ProtocolRecyclerViewAdapter(DailyScheduleActivity2 parent, DatabaseReference db, String protocolKey, FirebaseRecyclerOptions<Hour> options) {
super(options);
mParentActivity = parent;
}
@NonNull
@Override
public HourHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_protocol_row2, parent, false);
return new HourHolder(view);
}
@Override
public void onBindViewHolder(@NonNull HourHolder holder, int position, final Hour currentHour) {
holder.mHourCheckBox.setText(currentHour.toString());
//https://stackoverflow.com/questions/25646048/how-to-convert-local-time-to-am-pm-time-format-using-jodatime
LocalTime time = new LocalTime(currentHour.getMilitaryHour(), 0);
DateTimeFormatter fmt = DateTimeFormat.forPattern("h:mm a");
holder.mHour.setText(fmt.print(time));
holder.mOpenTasks.setOnClickListener(null);
holder.mOpenTasks.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DialogFragment hourlyTasksFragment = new HourlyTaskDialogFragment().newInstance(currentHour);
hourlyTasksFragment.show(mParentActivity.getSupportFragmentManager(), "HourlyTasks");
}
});
}
class HourHolder extends RecyclerView.ViewHolder {
final TextView mHourCheckBox;
final ImageView mOpenTasks;
final TextView mHour;
HourHolder(View view) {
super(view);
mHourCheckBox = (TextView) view.findViewById(R.id.cb_hour_all);
mOpenTasks = (ImageView) view.findViewById(R.id.open_tasks);
mHour = (TextView) view.findViewById(R.id.hour);
}
}
}
@Override
public void onDialogPositiveClick(Bundle bundle) {
Hour hour = bundle.getParcelable("hour");
mDatabase.child(protocolKey).child(String.valueOf(hour.getMilitaryHour())).setValue(hour);
mProtocolAdapter.notifyDataSetChanged();
}
@Override
protected void onStart() {
super.onStart();
mProtocolAdapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
mProtocolAdapter.stopListening();
}
}