我试图在有关自定义日历的项目中从ListAdapter迁移到PagedListAdapter。 日历是通过垂直滚动的recyclerview实现的,日历的每个数据都是从连接到dao的viewmodel中获取的。
问题是,当使用listadapter时,整个项目已经在内存中准备好了,因此在启动时使用scrollToPosition方法将recyclerview的位置初始化为当前日期,或者在用户选择时转到特定的日期位置,在PagedListAdapter NullPointerException中没有问题启用占位符时会发生这种情况,而禁用占位符时甚至什么也不会发生。
就我而言,我使用GridLayoutManager和setSpanSizeLookup来区分视图类型。
GridLayoutManager manager = new GridLayoutManager(getApplicationContext(), 7, LinearLayoutManager.VERTICAL, false);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int i) {
//if (adapter.getCurrentList().get(i) == null) return 0;
if (adapter.getItemViewType(i) == CalendarAdapter.HEADER_TYPE) {
return 7;
}
return 1;
}
});
并在CalendarAdapter中,
@Override
public int getItemViewType(int position) {
Item item = getItem(position);
if (item.getItemEntity().isHeader()) {
return HEADER_TYPE;
} else if (item.getItemEntity().getCalendar() == null) {
return EMPTY_TYPE;
} else {
return CELL_TYPE;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
if (i == HEADER_TYPE) {
CalendarHeaderBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),
R.layout.calendar_header, viewGroup, false);
return new HeaderViewHolder(binding);
} else if (i == EMPTY_TYPE) {
CalendarEmptyBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),
R.layout.calendar_empty, viewGroup, false);
return new EmptyViewHolder(binding);
} else {
CalendarCellBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),
R.layout.calendar_cell, viewGroup, false);
return new CellViewHolder(binding);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
int viewType = getItemViewType(i);
if (viewType == HEADER_TYPE) {
HeaderViewHolder holder = (HeaderViewHolder) viewHolder;
Item item = getItem(i);
HeaderViewModel model = new HeaderViewModel();
model.data.setValue(item);
holder.setHeader(model);
} else if (viewType == EMPTY_TYPE) {
EmptyViewHolder holder = (EmptyViewHolder) viewHolder;
EmptyViewModel model = new EmptyViewModel();
holder.setEmpty(model);
} else if (viewType == CELL_TYPE) {
CellViewHolder holder = (CellViewHolder) viewHolder;
Item item = getItem(i);
CellViewModel model = new CellViewModel();
model.data.setValue(item);
holder.setCell(model);
holder.binding.layoutBorder.setBackgroundResource(currentFocus == i ? R.drawable.item_border : 0);
}
}
在MainActivity中,
itemViewModel = ViewModelProviders.of(this).get(ItemViewModel.class);
itemViewModel.getAllItems().observe(this, new Observer<PagedList<Item>>() {
@Override
public void onChanged(@Nullable PagedList<Item> items) {
adapter.submitList(items);
}
});
public void goToCurrentDate() {
new Thread(new Runnable() {
@Override
public void run() {
final int position = itemViewModel.getPosition(calendar);
binding.rv.post(new Runnable() {
@Override
public void run() {
binding.rv.scrollToPosition(position);
binding.rv.stopScroll();
}
});
}
}).start();
}
我尝试为占位符分配空的viewholder,但效果非常差。只能猜测跨度大小上的差异可能很重要。