Fast scroll in ListView

Fast scroll in ListView

Sometimes when the list is very big, We need to make a fast scroll view. FastScroll is something like that:

Now we leart how to make a fast scroll in listView.
We need these things:

-Style in values-v14.
-Style.
-Colors.
-Layout.
-An adapter for list.
-Activity.

in directory values-v14/styles.xml we have to add three things:
fastScrollThumbDrawable
fastScrollTextColor
fastScrollPreviewBackgroundRight

<?xml version="1.0" encoding="utf-8"?>
<resources>
 
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- API 14 theme customizations can go here. -->
        <item name="android:fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
        <item name="android:fastScrollTextColor">@android:color/white</item>
        <item name="android:fastScrollPreviewBackgroundRight">@color/apptheme_color</item>
    </style>
 
</resources>

In directory values/styles.xml

<resources>
 
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
        <item name="android:fastScrollTextColor">@android:color/white</item>
        <item name="android:fastScrollPreviewBackgroundRight">@color/apptheme_color</item>
    </style>
 
</resources>

In Colors we have to add one color:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="apptheme_color">#DA4A38</color>
</resources>

You can doing without style, so you can skip last steps, and start since here:

The color of the indicator is your colorAccent

You can find the complete code in GitHub

res/layout/list_item

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

In activity_layout our listView.

<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.javier.fastscrollerwithandroidstyle.MainActivity">
 
    <ListView
        android:id="@+id/activity_main_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbarStyle="outsideOverlay" />
</RelativeLayout>

Our ListAdapter

public class ListAdapter extends ArrayAdapter<String> implements SectionIndexer {
 
    HashMap<String, Integer> mapIndex;
    String[] sections;
    List<String> fruits;
 
    public ListAdapter(Context context, List<String> fruitList) {
        super(context, R.layout.list_item, fruitList);
 
        this.fruits = fruitList;
        mapIndex = new LinkedHashMap<String, Integer>();
 
        for (int x = 0; x < fruits.size(); x++) {
            String fruit = fruits.get(x);
            String ch = fruit.substring(0, 1);
            ch = ch.toUpperCase(Locale.US);
 
            // HashMap will prevent duplicates
            mapIndex.put(ch, x);
        }
 
        Set<String> sectionLetters = mapIndex.keySet();
 
        // create a list from the set to sort
        ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
 
        Log.d("sectionList", sectionList.toString());
        Collections.sort(sectionList);
 
        sections = new String[sectionList.size()];
 
        sectionList.toArray(sections);
    }
 
    public int getPositionForSection(int section) {
        Log.d("section", "" + section);
        return mapIndex.get(sections[section]);
    }
 
    public int getSectionForPosition(int position) {
        Log.d("position", "" + position);
        return 0;
    }
 
    public Object[] getSections() {
        return sections;
    }
}

In our activity

public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        ListView listView = (ListView) findViewById(R.id.activity_main_list);
        listView.setFastScrollEnabled(true);
        String[] fruits = getResources().getStringArray(R.array.fruits_array);
 
        List<String> fruitList = Arrays.asList(fruits);
        ListAdapter listAdapter = new ListAdapter(this, fruitList);
        listView.setAdapter(listAdapter);
 
    }
}

And in our strings, something like that:

<resources>
    <string name="app_name">FastScrollerWithAndroidStyle</string>
    <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>
</resources>

You can find the complete code in GitHub

Infinitely Scrolling List

When you use a List or Grid, sometimes common requirement is to dynamically load more data as the user keeps scrolling down making it a potentially infinite scrolling list. This blog will guide you on how to implement this feature in your app.

Infinitely Scrolling List

We will need is our InfiniteScrollListener class that will implement OnScrollListener. Let’s jump right in and see the code for this class.

public abstract class InfiniteScrollListener implements AbsListView.OnScrollListener {
    private int mBufferItemCount = 10;
    private int mCurrentPage = 0;
    private int mItemCount = 0;
    private boolean mIsLoading = true;

    public InfiniteScrollListener(int bufferItemCount) {
        this.mBufferItemCount = bufferItemCount;
    }

    public abstract void loadMore(int page, int totalItemsCount);

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // Do Nothing
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (totalItemCount < mItemCount) {
            this.mItemCount = totalItemCount;
            if (totalItemCount == 0) {
                this.mIsLoading = true;
            }
        }

        if (mIsLoading && (totalItemCount > mItemCount)) {
            mIsLoading = false;
            mItemCount = totalItemCount;
            mCurrentPage++;
        }

        if (!mIsLoading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + mBufferItemCount)) {
            loadMore(mCurrentPage + 1, totalItemCount);
            mIsLoading = true;
        }
    }

}

Then in our onCreate of Activity We must put this:

mGridView.setOnScrollListener(new InfiniteScrollListener(5) {
            @Override
            public void loadMore(int page, int totalItemsCount) {
                mProgressDialog.show();
                // your code
            }
        });

Download code