【问题标题】:Show selected item on RecyclerView in Sync with ViewPager在与 ViewPager 同步的 RecyclerView 上显示所选项目
【发布时间】:2016-02-26 06:28:06
【问题描述】:

我试图让 ViewPager 和 RecyclerView 在显示图像时同步工作。 ViewPager 包含一个 ImageView ,它显示全尺寸图像,而回收器视图显示以前和即将到来的图像的缩略图。

如果用户在 ViewPager 上滑动,则 RecyclerView 会向左/向右同步移动。如果用户滚动然后单击照片,ViewPager 会设置该位置。

这一切都有效,只是为我的应用提供背景。

我卡住的部分是显示当前在 RecyclerView from onPageSelected 中选择的缩略图周围的边框。被认为被选中的元素是当前在 ViewPager 上显示的元素

许多其他问题使用 onClickListener 来处理这个问题。我的 onClickListener 只是调用

viewPager.setCurrentItem(index)

因此,无论何时选择一个项目,都会调用 onPageSelected,自然地来自 ViewPager 或来自单击事件。所以这是我觉得我需要设置边界的地方。

到目前为止,我使用了一些技巧,因为图像数量只有 20 个。

for (int i = 0, ii = recyclerViewAdapter.getItemCount(); i < ii; i++) {
        //RecyclerView.ViewHolder holder = recyclerView.findViewHolderForItemId(recyclerViewAdapter.getItemId(i));
        RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(position);

        if (holder instanceof RecyclerViewAdapter.RecyclerViewHolder) {
            if (i == position) {
                ...
                ((RecyclerViewAdapter.RecyclerViewHolder) holder).getViewHolderContainer().setBackground(border);
            } else {
                ((RecyclerViewAdapter.RecyclerViewHolder) holder).getViewHolderContainer().setBackground(null);
            }
        }
    }

这不起作用。如果 get 是正确的位置,因为我是由 ViewPager 提供的,但是在“位置”检索 ViewHolder 的方法似乎都不起作用。

所以,毕竟,我的问题是,是否有人可以向我推荐一种干净的方法(或者此时甚至是 hack),它可以让我根据 ViewPager 的 onPageSelected 的位置更新元素的当前位置.

谢谢。

【问题讨论】:

  • 确实 notifyItemChanged(position) 更新了该位置的视图
  • 嗨,ankitagrawal。数据集没有任何变化。我所做的只是在结构上改变视图的属性。万一我错了,我确实尝试过但没有运气:(

标签: android android-fragments android-viewpager android-recyclerview


【解决方案1】:

所以我最终使用两个接口来完成这项工作。不需要丑陋的循环黑客。

ViewPager.OnPageChangeListener 和 OnChildAttachStateListener。

基本上我的问题是,如果我从 RecyclerView 中当前选定的项目滚动出去,那么以后我无法取消选择该项目,因为 ViewHolder 被回收或为空。基本上我无法访问上一个视图以取消选择它,因此当您滚动浏览它时最终会选择多个项目。

所以使用 ViewPager 很容易。

@Override
public void onPageSelected(int position)
    int previousItemPos = currentItemPos; //currentItemPos is a class attr
    currentItemPos = position;
    int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation()
    if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270) { //portrait
        portraitScroll(position) //scrolls the recyclerView to currently selected item based on viewWidth
    } else if .. landscape do the same
    changeItem(position, previousItemPos);
}

@Override
public void onChildViewAttachedToWindow(View view) {
    int childPosition = recyclerView.getChildAdapterPosition(view);
    if (childPosition == currentItemPos) {
        highlightItem(view); //applies an effect
    }
}

@Override
public void onChildViewDetachedToWindow(View view) {
    unHighlightItem(view);
}

private void changeItem(int newItem, int oldItem) {
    ViewHolder holder = recyclerView.findViewHolderForItemId(recyclerView.getItemId(newItem));
    if (holder instance of RecyclerViewHolder) {
        highlightItem((RecyclerViewHolder) holder).getViewHolderContainer());
    }
    ViewHolder oldHolder = recyclerView.findViewHolderForItemId(recyclerView.getItemId(oldItem));
    if (oldHolder instance of RecyclerViewHolder) {
        unHighlightItem((RecyclerViewHolder) holder).getViewHolderContainer());
    }

所以基本上每次我们滚动以使 ViewPager 中当前选定的项目消失时,我们都会在它分离时取消选择它。如果我们回滚到它并且位置没有改变,我们重新选择它。

如果 ViewPager 改变了 item,首先我们根据每个 RecyclerViews 视图的宽度滚动到那个 item,然后我们在 onPageSelected 中选择它。

【讨论】:

  • 这太棒了。我遇到了同样的问题,你的回答帮助我解决了这个问题。荣誉马特
  • 能否请您发布整个代码?因为我必须解决同样的问题,但在我的情况下你的解决方案不起作用。
  • @MachoProgrammer 这是大约 6 个月前给我的一次面试挑战的一部分。这是该项目的github。寻找 FragMain.java。 github.com/Trestal/FlickrLab
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多