当前位置: 首页 > 知识库问答 >
问题:

如何将快速滚动器添加到RecyclerView视图

笪波鸿
2023-03-14

在ListView上,您可以使用一个快速滚动条,它允许您拖动滚动条,以便轻松滚动到您希望的任何位置(使用fastScrollEnabled属性)

再加上“SectionIndexer”类和一些可选的属性,您可以在使用此滚动条时看到一个漂亮的弹出窗口(此处链接)。

这种东西显示在联系人应用程序上,这样你就可以很容易地滚动到特定的字母。

RecyclerView似乎没有这些。甚至连快速滚动都没有。

如何为RecyclerView添加快速滚动功能?

共有3个答案

汤洋
2023-03-14

Android支持库26.0.0现在支持快速滚动启用

RecyclerView的新fastScrollEnabled布尔标志。

如果启用,则必须设置快ScrollHorizontalThumbDrawable、快ScrollHorizontalTrackDrawable、快ScrollVerticalThumbDrawable和快ScrollVerticalTrackDrawable。

样本-https://android.jlelse.eu/fast-scrolling-with-recyclerview-2b89d4574688

魏澄邈
2023-03-14

新答案:随着时间的推移,我注意到我最初的答案与其他解决方案相比有一些缺点,尤其是对于ViewPager中的片段。

我建议要么使用android-x解决方案,以防你不需要气泡,要么使用第三方库(这是一个不错的库),以防万一。

旧答案:

由于所有第三方库都存在问题,我决定收集我能找到的内容(主要是从这里),修复所有内容并发布我自己的回收器快速滚动的POCView:

https://github . com/AndroidDeveloperLB/lollipopcontactsrecyclerviewsfastscroller

用法:

> < li>

进行回收查看。实现BubbleTextGetter的适配器,它在数据中给定一个位置,将返回文本以显示在bubble-popup中。

将FastScroller放置在包含RecyclerView的布局内(可能在右侧区域)。

自定义快速卷筒快速卷起器

一些缺点:

  1. 不支持方向更改,但可能很容易修复
  2. 它不支持其他裁员经理。仅限LinearLayoutManager
  3. 需要API 11及以上版本

代码

BubbleTextGetter

public interface BubbleTextGetter
  {
  String getTextToShowInBubble(int pos);
  }

recycler _ view _ fast _ scroller _ _ fast _ scroller . XML

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools"
       android:layout_width="wrap_content"
       android:layout_height="match_parent">

  <TextView
    android:id="@+id/fastscroller_bubble"
    android:layout_gravity="right|end"
    android:gravity="center"
    android:textSize="48sp" tools:text="A"
    android:layout_width="wrap_content"
    android:textColor="#FFffffff"
    android:layout_height="wrap_content"
    android:background="@drawable/recycler_view_fast_scroller__bubble"
    android:visibility="visible"/>

  <ImageView
    android:id="@+id/fastscroller_handle"
    android:layout_width="wrap_content"
    android:layout_marginRight="8dp"
    android:layout_marginLeft="8dp"
    android:layout_height="wrap_content"
    android:src="@drawable/recycler_view_fast_scroller__handle"/>

</merge>

主要活动

...
fastScroller=(FastScroller)findViewById(R.id.fastscroller);
fastScroller.setRecyclerView(recyclerView);

快速卷轴

public class FastScroller extends LinearLayout
  {
  private static final int BUBBLE_ANIMATION_DURATION=100;
  private static final int TRACK_SNAP_RANGE=5;

  private TextView bubble;
  private View handle;
  private RecyclerView recyclerView;
  private final ScrollListener scrollListener=new ScrollListener();
  private int height;

  private ObjectAnimator currentAnimator=null;

  public FastScroller(final Context context,final AttributeSet attrs,final int defStyleAttr)
    {
    super(context,attrs,defStyleAttr);
    initialise(context);
    }

  public FastScroller(final Context context)
    {
    super(context);
    initialise(context);
    }

  public FastScroller(final Context context,final AttributeSet attrs)
    {
    super(context,attrs);
    initialise(context);
    }

  private void initialise(Context context)
    {
    setOrientation(HORIZONTAL);
    setClipChildren(false);
    LayoutInflater inflater=LayoutInflater.from(context);
    inflater.inflate(R.layout.recycler_view_fast_scroller__fast_scroller,this,true);
    bubble=(TextView)findViewById(R.id.fastscroller_bubble);
    handle=findViewById(R.id.fastscroller_handle);
    bubble.setVisibility(INVISIBLE);
    }

  @Override
  protected void onSizeChanged(int w,int h,int oldw,int oldh)
    {
    super.onSizeChanged(w,h,oldw,oldh);
    height=h;
    }

  @Override
  public boolean onTouchEvent(@NonNull MotionEvent event)
    {
    final int action=event.getAction();
    switch(action)
      {
      case MotionEvent.ACTION_DOWN:
        if(event.getX()<handle.getX())
          return false;
        if(currentAnimator!=null)
          currentAnimator.cancel();
        if(bubble.getVisibility()==INVISIBLE)
          showBubble();
        handle.setSelected(true);
      case MotionEvent.ACTION_MOVE:
        setPosition(event.getY());
        setRecyclerViewPosition(event.getY());
        return true;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_CANCEL:
        handle.setSelected(false);
        hideBubble();
        return true;
      }
    return super.onTouchEvent(event);
    }

  public void setRecyclerView(RecyclerView recyclerView)
    {
    this.recyclerView=recyclerView;
    recyclerView.setOnScrollListener(scrollListener);
    }

  private void setRecyclerViewPosition(float y)
    {
    if(recyclerView!=null)
      {
      int itemCount=recyclerView.getAdapter().getItemCount();
      float proportion;
      if(handle.getY()==0)
        proportion=0f;
      else if(handle.getY()+handle.getHeight()>=height-TRACK_SNAP_RANGE)
        proportion=1f;
      else
        proportion=y/(float)height;
      int targetPos=getValueInRange(0,itemCount-1,(int)(proportion*(float)itemCount));
      recyclerView.scrollToPosition(targetPos);
      String bubbleText=((BubbleTextGetter)recyclerView.getAdapter()).getTextToShowInBubble(targetPos);
      bubble.setText(bubbleText);
      }
    }

  private int getValueInRange(int min,int max,int value)
    {
    int minimum=Math.max(min,value);
    return Math.min(minimum,max);
    }

  private void setPosition(float y)
    {
    int bubbleHeight=bubble.getHeight();
    int handleHeight=handle.getHeight();
    handle.setY(getValueInRange(0,height-handleHeight,(int)(y-handleHeight/2)));
    bubble.setY(getValueInRange(0,height-bubbleHeight-handleHeight/2,(int)(y-bubbleHeight)));
    }

  private void showBubble()
    {
    AnimatorSet animatorSet=new AnimatorSet();
    bubble.setVisibility(VISIBLE);
    if(currentAnimator!=null)
      currentAnimator.cancel();
    currentAnimator=ObjectAnimator.ofFloat(bubble,"alpha",0f,1f).setDuration(BUBBLE_ANIMATION_DURATION);
    currentAnimator.start();
    }

  private void hideBubble()
    {
    if(currentAnimator!=null)
      currentAnimator.cancel();
    currentAnimator=ObjectAnimator.ofFloat(bubble,"alpha",1f,0f).setDuration(BUBBLE_ANIMATION_DURATION);
    currentAnimator.addListener(new AnimatorListenerAdapter()
    {
    @Override
    public void onAnimationEnd(Animator animation)
      {
      super.onAnimationEnd(animation);
      bubble.setVisibility(INVISIBLE);
      currentAnimator=null;
      }

    @Override
    public void onAnimationCancel(Animator animation)
      {
      super.onAnimationCancel(animation);
      bubble.setVisibility(INVISIBLE);
      currentAnimator=null;
      }
    });
    currentAnimator.start();
    }

  private class ScrollListener extends OnScrollListener
    {
    @Override
    public void onScrolled(RecyclerView rv,int dx,int dy)
      {
      View firstVisibleView=recyclerView.getChildAt(0);
      int firstVisiblePosition=recyclerView.getChildPosition(firstVisibleView);
      int visibleRange=recyclerView.getChildCount();
      int lastVisiblePosition=firstVisiblePosition+visibleRange;
      int itemCount=recyclerView.getAdapter().getItemCount();
      int position;
      if(firstVisiblePosition==0)
        position=0;
      else if(lastVisiblePosition==itemCount-1)
        position=itemCount-1;
      else
        position=firstVisiblePosition;
      float proportion=(float)position/(float)itemCount;
      setPosition(height*proportion);
      }
    }
  }
贺雪松
2023-03-14

前几天碰到这种情况,无意中发现了这个问题。以下是我为RecyclerView实现FastScroll的示例:

尝试运行示例应用程序,并仔细阅读代码以查看简单RecyclViewFastScroller小部件的相当简单的用法。有关于github的信息,但我将在这里包含垂直快速滚动的基本用法。

有关完整示例,请参阅存储库中的示例应用程序。

在RecyclView所在的活动或片段XML中,包含一个VerticalRecyclViewFastScroller对象。以下示例将处于相对布局中:

...
  <android.support.v7.widget.RecyclerView
      android:id="@+id/recyclerView"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>


  <xyz.danoz.recyclerviewfastscroller.vertical.VerticalRecyclerViewFastScroller
      android:id="@+id/fast_scroller"
      android:layout_width="@dimen/however_wide_you_want_this"
      android:layout_height="match_parent"
      android:layout_alignParentRight="true"
    />
...

在您以编程方式设置布局的片段或活动中,将快速滚动器连接到回收器:

...
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View rootView = inflater.inflate(R.layout.recycler_view_frag, container, false);
      ...

      // Grab your RecyclerView and the RecyclerViewFastScroller from the layout
      RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
      VerticalRecyclerViewFastScroller fastScroller = (VerticalRecyclerViewFastScroller) rootView.findViewById(R.id.fast_scroller);

      // Connect the recycler to the scroller (to let the scroller scroll the list)
      fastScroller.setRecyclerView(recyclerView);

      // Connect the scroller to the recycler (to let the recycler scroll the scroller's handle)
      recyclerView.setOnScrollListener(fastScroller.getOnScrollListener());

      ...
      return rootView;
  }
...

希望这有帮助!

编辑:现在增加了对Android-Lollipop-联系人样式部分指示器的支持!查看示例应用程序的实现以获取详细信息。

 类似资料:
  • 我有一个简单的ListView程序,其中试图附加滚动条。上下滚动时列表没有移动,在这里,列表应该相应地移动。似乎,我无法正确设置contentItem。寻找一些提示。 请在下面找到我的示例核心,于是我在listView中添加了一个垂直滚动条。rolesListModel是我的模特。 主要的qml

  • 我正在创建一个简单的应用程序供个人使用,我被卡住了,因为我需要从我的滚动视图中添加/删除文本。在屏幕截图下面的蓝色方块是我的滚动视图和邮件按钮(占位符)需要打开一个弹出窗口,我可以把2个值在2个不同的框,一个字符串和一个双。 Main_Activity 我知道如何做几乎所有的事情,但我不知道如何添加一个文本,每次我点击邮件按钮,它应该像这样,当我点击它 这就是完成时应该做的。汽车模块的左按钮是“从

  • 问题内容: 我有一个要在HTML5中添加一个滚动条的表。我希望表格显示十行,然后用户可以向下滚动以查看其他歌曲。如何添加滚动条? 这是我在HTML5中的表格代码: 这是我的CSS代码: 问题答案: 如果您有表列标题,并且不想滚动这些标题,那么此解决方案可以为您提供帮助: 这种解决方案需要和内部标签元素。 注意 :如果您确定垂直滚动条始终存在,则可以使用css3 calc属性使thead细胞与tbo

  • 问题内容: 我们有一个收藏夹视图。我制作了一个日历,水平显示日期&水平滚动日期。现在在屏幕上,我只看到3-4个日期。现在我想在显示日历屏幕时自动滚动到特定的选定日期,所以我要滚动到的日期尚不可见。 为此,我得到了特定单元格的索引路径。现在,我尝试将其滚动到特定的indexpath。 请告诉我如何实施? 问题答案: 在您的控制器中,您可以编写代码以滚动到集合视图的特定索引路径。

  • 我是kotlin的新手,这是我的适配器代码,它可以查找,我没有问题,现在,我需要为它实现click listener,下面是我的代码: 我想添加click listener,我以前在viewholder类中实现click listener 我在科特林怎么做?我打了这么多的平手,但都没有成功

  • 我的页面中有一个ui视图。单击某个按钮时,将加载ui视图并替换为某个HTML。我想将页面向下滚动到页面刚加载的部分。 这有可能吗?提前感谢