使用PagedListAdapter的scrollToPosition方法

时间:2019-11-09 13:30:22

标签: android

我试图在有关自定义日历的项目中从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,但效果非常差。只能猜测跨度大小上的差异可能很重要。

0 个答案:

没有答案