android - 在 RecyclerView 上与 ViewPager 同步显示所选项目

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

我正在尝试让 ViewPager 和 RecyclerView 在显示图像时同步工作。 ViewPager 包含一个 ImageView,它显示完整尺寸的图像,回收器 View 显示以前和即将出现的图像的缩略图。

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

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

我遇到的问题是在 RecyclerView 中当前选择的缩略图周围显示边框从 onPageSelected。被视为选定的元素是当前显示在 ViewPager 上的元素

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

viewPager.setCurrentItem(index)

因此,只要选择一个项目,就会自然地从 ViewPager 或单击事件调用 onPageSelected。所以这是我觉得需要设置边框的地方。

到目前为止,我使用了一些 hack,因为图像数量只有 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 的方法似乎都不起作用。

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

谢谢您。

最佳答案

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

ViewPager.OnPageChangeListener 和 OnChildAttachStateListener。

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

所以使用 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 更改了项目,首先我们根据每个 RecyclerViews View 的宽度滚动到该项目,然后在 onPageSelected 中选择它。

关于android - 在 RecyclerView 上与 ViewPager 同步显示所选项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35550178/

相关文章:

android - 使用 ViewPager 和 PassByValue 滑动页面时执行 onTouchEvent

android - 提前获取星期几

java - XML 不会显示保存的 TimePicker 数据 (CurrentHour)

android - 在 Firebase 中获取唯一推送 ID

java - 创建 map v2 扩展 fragment 时出错

android - 单个 ViewModel 中的多个 LiveData 对象

Android ViewPager,如何使兄弟 View 变小变暗

android - mapView 在点击时显示覆盖细节

android - 从 Fragments 访问主要 Activity FloatingActionButton

android - CoordinatorLayout 中 ViewPager 顶部的空白