web-dev-qa-db-fra.com

Android alphabétique défilement rapide dans RecyclerView avec barre d'outils Réduire

Dans mon application, j'ai activity_main.xml comme ceci: -

<Coordinator Layout>
   <AppBarLayout>
      <CollapsingToolbarLayout>
           <ImageView/>
           <Toolbar/>
       </CollapsingToolbarLayout>
   </AppBarLayout>
   <RecyclerView/>
</Coordinating Layout>

Layout.xml ----- >>>

<?xml version="1.0" encoding="utf-8"?>



<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    xmlns:ads="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@drawable/theme_background"
    Android:id="@+id/drawerlayout"
    >


    <Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:app="http://schemas.Android.com/apk/res-auto"
        xmlns:tools="http://schemas.Android.com/tools"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:fitsSystemWindows="true"
        Android:id="@+id/activity_main_id"
        tools:context="objectdistance.ajai.ram.sita.gallery.MainActivity">

        <Android.support.design.widget.AppBarLayout
            Android:id="@+id/app_bar_layout"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:fitsSystemWindows="true"
            Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">


            <Android.support.design.widget.CollapsingToolbarLayout
                Android:id="@+id/collapsing_toolbar"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:contentScrim="?attr/colorPrimary"
                app:expandedTitleMarginStart="48dp"
                app:expandedTitleMarginEnd="64dp"
                Android:fitsSystemWindows="true">



                <ImageView
                    Android:id="@+id/imagetoolbar"
                    Android:layout_width="match_parent"
                    Android:layout_height="200dp"
                    Android:scaleType="centerCrop"
                    Android:fitsSystemWindows="true"
                    Android:foreground="@drawable/image_header_foreground"
                    app:layout_scrollFlags="scroll"
                    app:layout_collapseMode="parallax"/>

                <Android.support.v7.widget.Toolbar
                    Android:id="@+id/toolbar"
                    Android:layout_width="match_parent"
                    Android:layout_height="?attr/actionBarSize"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    Android:background="@drawable/theme_background"
                    app:layout_collapseMode="pin" >

                    <Spinner
                        Android:id="@+id/spinner_nav"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"

                        Android:dropDownVerticalOffset="?attr/actionBarSize" />

                </Android.support.v7.widget.Toolbar>

            </Android.support.design.widget.CollapsingToolbarLayout>


        </Android.support.design.widget.AppBarLayout>




        <Android.support.v7.widget.RecyclerView
            Android:id="@+id/list"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />




    </Android.support.design.widget.CoordinatorLayout>


    <ListView
        Android:layout_width="200dp"
        Android:layout_height="match_parent"
        Android:id="@+id/navlist"
        Android:background="#dedede"
        Android:layout_gravity="start" />

</Android.support.v4.widget.DrawerLayout>

Maintenant, je veux inclure un défilement rapide vers ma vue de recyclage de sorte que la date de l'image puisse être contextuelle lors du défilement.

Exemple d'image d'une telle barre de défilement: - Scrolling

J'ai cherché cela et essayé d'utiliser quelques bibliothèques, mais je pense qu'en raison de la réduction de la barre d'outils, la barre de défilement ne fonctionne pas correctement.

Capture d'écran de la bibliothèque de défilement utilisée: - My device

Ici, dans mon cas, la barre de défilement commence par le haut et le calcul du défilement n'est pas non plus approprié.

Aidez-nous à résoudre ce problème.

Merci

42

nous voulons quelques connaissances de SectionIndexer. Voici Doc de SectionIndexer .

Nous devons définir la méthode TRUE setFastScrollEnabled(true), qui est utilisée avec la LISTVIEW ....... Vous pouvez utiliser recyclerview au lieu de listView dans l'exemple ci-dessous ....

c'est une activité

public class FastScoll extends ListActivity {

    ListView fruitView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fast_scoll);

        fruitView = (ListView) findViewById(Android.R.id.list);

        fruitView.setFastScrollEnabled(true);
        String[] fruits = getResources().getStringArray(R.array.fruits_array);

        final List<String> fruitList = Arrays.asList(fruits);
        Collections.sort(fruitList);
        setListAdapter(new ListAdapter(this, fruitList));

        fruitView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent, View arg1,
                                    int position, long arg3) {
                Log.e("sushildlh",fruitList.get(position));
            }
        });

    }
}

c'est le fichier activity_fast_scoll.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:padding="5dp" >

    <ListView
        Android:id="@Android:id/list"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:scrollbarStyle="outsideOverlay" />

</RelativeLayout>

et ceci est mon adaptateur personnalisé avec SectionIndexer....

public class ListAdapter extends ArrayAdapter<String> implements SectionIndexer {

    String[] sections;
    List<String> fruits;
    List<String> sectionLetters=new ArrayList<String>();

    public ListAdapter(Context context, List<String> fruitList) {
        super(context, Android.R.layout.simple_list_item_1, fruitList);
        this.fruits = fruitList;

        for (int x = 0; x < fruits.size(); x++) {
            String fruit = fruits.get(x);
            String ch = fruit.charAt(0)+"";
            ch = ch.toUpperCase(Locale.US);

            sectionLetters.add(ch);
        }

        ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);

        sections = new String[sectionList.size()];

        sectionList.toArray(sections);
    }

    public int getPositionForSection(int section) {

        Log.e("sushildlh", "" + section);
        return section;
    }

    public int getSectionForPosition(int position) {

        Log.d("sushildlh", "" + position);
        return position;
    }

    public Object[] getSections() {
        return sections;
    }
}

c'est un tableau de fruits dans le fichier string.xml.

 <string-array name="fruits_array">
            <item>Apples</item>
            <item>Apricots</item>
            <item>Avocado</item>
            <item>Annona</item>
            <item>Banana</item>
            <item>Bilberry</item>
            <item>Blackberry</item>
            <item>Custard Apple</item>
            <item>Clementine</item>
            <item>Cantalope</item>
            <item>Coconut</item>
            <item>Currant</item>
            <item>Cherry</item>
            <item>Cherimoya</item>
            <item>Date</item>
            <item>Damson</item>
            <item>Durian</item>
            <item>Elderberry</item>
            <item>Fig</item>
            <item>Feijoa</item>
            <item>Grapefruit</item>
            <item>Grape</item>
            <item>Gooseberry</item>
            <item>Guava</item>
            <item>Honeydew melon</item>
            <item>Huckleberry</item>
            <item>Jackfruit</item>
            <item>Juniper Berry</item>
            <item>Jambul</item>
            <item>Jujube</item>
            <item>Kiwi</item>
            <item>Kumquat</item>
            <item>Lemons</item>
            <item>Limes</item>
            <item>Lychee</item>
            <item>Mango</item>
            <item>Mandarin</item>
            <item>Mangostine</item>
            <item>Nectaraine</item>
            <item>Orange</item>
            <item>Olive</item>
            <item>Prunes</item>
            <item>Pears</item>
            <item>Plum</item>
            <item>Pineapple</item>
            <item>Peach</item>
            <item>Papaya</item>
            <item>Passionfruit</item>
            <item>Pomegranate</item>
            <item>Pomelo</item>
            <item>Raspberries</item>
            <item>Rock melon</item>
            <item>Rambutan</item>
            <item>Strawberries</item>
            <item>Sweety</item>
            <item>Salmonberry</item>
            <item>Satsuma</item>
            <item>Tangerines</item>
            <item>Tomato</item>
            <item>Ugli</item>
            <item>Watermelon</item>
            <item>Woodapple</item>
        </string-array>

et enfin c'est la sortie de ces codes ....

oo1o2

N'hésitez pas à demander si vous êtes coincé quelque part entre le code ....

Remarque: - L'image FastScroll sera différente dans différentes versions de Android (par exemple: -Lollipop, Marshmallow, etc.) ci-dessous, la sortie est pour Lollipop

Lollipop

Pour Défilement rapide alphabétique personnalisé ajoutez simplement ces 2 lignes dans votre style.xml fichier dans AppTheme.

<item name="Android:fastScrollTextColor">@color/apptheme_color</item>         //this is used for the color of the Alphabetical Fast scrollView
<item name="Android:fastScrollPreviewBackgroundRight">@drawable/bg_default_focused_holo_light</item>          //this is the image or and drawable file you want to set on Alphabetical Fast scrollView

Sortie Scorll rapide personnalisée: -

ouy

12
sushildlh

Il y a une bonne bibliothèque ici avec ceci exemple . Il y a aussi un bon tutoriel ici avec cet exemple dans Github .

Usage:

créer un RecyclerView.Adapter qui implémente BubbleTextGetter, qui, étant donné une position dans les données, renverra le texte à afficher dans la bulle contextuelle. positionnez le FastScroller à l'intérieur de la disposition qui contient le RecyclerView (probablement dans la bonne zone).

Personnalisez le FastScroller quelques inconvénients:

ne prend pas en charge le changement d'orientation, mais il est probablement facile à corriger. ne prend pas en charge d'autres gestionnaires de disposition. Seul LinearLayoutManager a besoin de l'API 11 et supérieure.

Code:

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>

Maintenant, ce ScrollListener:

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);
      }
    }
  }

Ce LinearLayout personnalisé:

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();
    }

La dernière étape de votre activité onCreate:

    setContentView(R.layout.activity_main);
    RecyclerView recyclerView =(RecyclerView)findViewById(R.id.activity_main_recyclerview);


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

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    xmlns:ads="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@drawable/theme_background"
    Android:id="@+id/drawerlayout">

    <Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:app="http://schemas.Android.com/apk/res-auto"
        xmlns:tools="http://schemas.Android.com/tools"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:fitsSystemWindows="true"
        Android:id="@+id/activity_main_id"
        tools:context="objectdistance.ajai.ram.sita.gallery.MainActivity">

        <Android.support.design.widget.AppBarLayout
            Android:id="@+id/app_bar_layout"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:fitsSystemWindows="true"
          Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <Android.support.design.widget.CollapsingToolbarLayout
                Android:id="@+id/collapsing_toolbar"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:contentScrim="?attr/colorPrimary"
                app:expandedTitleMarginStart="48dp"
                app:expandedTitleMarginEnd="64dp"
                Android:fitsSystemWindows="true">

                <ImageView
                    Android:id="@+id/imagetoolbar"
                    Android:layout_width="match_parent"
                    Android:layout_height="200dp"
                    Android:scaleType="centerCrop"
                    Android:fitsSystemWindows="true"
                    Android:foreground="@drawable/image_header_foreground"
                    app:layout_scrollFlags="scroll"
                    app:layout_collapseMode="parallax"/>

                <Android.support.v7.widget.Toolbar
                    Android:id="@+id/toolbar"
                    Android:layout_width="match_parent"
                    Android:layout_height="?attr/actionBarSize"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    Android:background="@drawable/theme_background"
                    app:layout_collapseMode="pin" >

                    <Spinner
                        Android:id="@+id/spinner_nav"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:dropDownVerticalOffset="?attr/actionBarSize" />

                </Android.support.v7.widget.Toolbar>

            </Android.support.design.widget.CollapsingToolbarLayout>

        </Android.support.design.widget.AppBarLayout>

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/activity_main_recyclerview"
        Android:layout_width="match_parent"
        Android:layout_height="@dimen/activity_main_height"
        Android:background="@Android:color/darker_gray" />
 </Android.support.design.widget.CoordinatorLayout>
</Android.support.v4.widget.DrawerLayout>
3
Cabezas