Android SearchableSpinner


Android SearchableSpinner Library Tutorial and Example.

What about if you have a spinner with plenty of items and you want to provide users with ability to search or filter those items.

What do you do then?

Well you have a solution is SearchableSpinner by @michaelprimez in SearcableSpinner.

Demo

Here's SearchableSpinner in action. The source for this is found in the example below.

Android Searchable Spinner

Installation

You can fetch SearchableSpinner via gradle. All you need do is add the following in your app level build.gradle and sync your project:

implementation 'gr.escsoft.michaelprimez.searchablespinner:SearchableSpinner:1.0.9'

How to Use

To use SearchableSpinner first go over to your layout where you want to add it and add the following:

<gr.escsoft.michaelprimez.searchablespinner.SearchableSpinner
        android:id="@+id/SearchableSpinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginRight="24dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:gravity="center_horizontal"
        app:StartSearchTintColor="@android:color/white"
        app:DoneSearchTintColor="@android:color/holo_purple"
        app:RevealViewBackgroundColor="@android:color/holo_purple"
        app:SearchViewBackgroundColor="@android:color/secondary_text_dark"
        app:ShowBorders="false"
        app:RevealEmptyText="Touch to select"
        app:SpinnerExpandHeight="300dp"/>

For java usage continue over to full example section.

Full Searchable Spinner Example

Gradle Scripts

Here are our gradle scripts in our build.gradle file(s).

(a). build.gradle(app)

Here's our app level build.gradle file. We have the dependencies DSL where we add our dependencies.

This file is called app level build.gradle since it's located in the app folder of the project.

If you are using Android Studio version 3 and above use implementation keyword while if you are using a version less than 3 then still use the compile keyword.

Once you've modified this build.gradle file you have to sync your project. Android Studio will indeed prompt you to do so.

implementation 'gr.escsoft.michaelprimez.searchablespinner:SearchableSpinner:1.0.9'

Resources.

Android platform provides a powerful and flexible way of adding static content as a resource.

These static content will also be packaged into the APK file. The static content will be stored either as a resource or as an asset.

Resources belong to a given type. These types can be:

  1. Drawable.
  2. Layout.
  3. Value.

Let's start by looking at the layout resources

(a). activity_main.xml

This layout will get inflated into the main activity's user interface. This will happen via the Activity's setContentView() method which will require us to pass it the layout.

We will do so inside the onCreate() method of Activity.

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context="gr.escsoft.michaelprimez.searchablespinnerexamples.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"/>

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

    <include layout="@layout/content_main"/>

</android.support.design.widget.CoordinatorLayout>
(b). content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="gr.escsoft.michaelprimez.searchablespinnerexamples.MainActivity"
    tools:showIn="@layout/activity_main">

    <gr.escsoft.michaelprimez.searchablespinner.SearchableSpinner
        android:id="@+id/SearchableSpinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginRight="24dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:gravity="center_horizontal"
        app:ShowBorders="true"
        app:BordersSize="1dp"
        app:RevealEmptyText="Touch to select"
        app:BoarderColor="@color/colorPrimary"
        app:SpinnerExpandHeight="250dp"/>

    <gr.escsoft.michaelprimez.searchablespinner.SearchableSpinner
        android:id="@+id/SearchableSpinner1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginRight="24dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:gravity="center_horizontal"
        app:StartSearchTintColor="@android:color/white"
        app:DoneSearchTintColor="@android:color/white"
        app:RevealViewBackgroundColor="@android:color/holo_blue_light"
        app:SearchViewBackgroundColor="@android:color/holo_blue_light"
        app:ShowBorders="true"
        app:BordersSize="1dp"
        app:BoarderColor="@android:color/holo_blue_light"
        app:SpinnerExpandHeight="0dp"/>

    <gr.escsoft.michaelprimez.searchablespinner.SearchableSpinner
        android:id="@+id/SearchableSpinner2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginRight="24dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:gravity="center_horizontal"
        app:StartSearchTintColor="@android:color/white"
        app:DoneSearchTintColor="@android:color/holo_purple"
        app:RevealViewBackgroundColor="@android:color/holo_purple"
        app:SearchViewBackgroundColor="@android:color/secondary_text_dark"
        app:ShowBorders="true"
        app:RevealEmptyText="Touch to select"
        app:SpinnerExpandHeight="300dp"
        app:ItemsDivider="@color/gray_400"
        app:DividerHeight="0.5dp"/>

    <gr.escsoft.michaelprimez.searchablespinner.SearchableSpinner
        android:id="@+id/SearchableSpinner3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginRight="24dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:gravity="center_horizontal"
        app:StartSearchTintColor="@android:color/white"
        app:DoneSearchTintColor="@android:color/holo_purple"
        app:RevealViewBackgroundColor="@android:color/holo_purple"
        app:SearchViewBackgroundColor="@android:color/secondary_text_dark"
        app:ShowBorders="false"
        app:BordersSize="4dp"
        app:RevealEmptyText="Touch to select"
        app:SpinnerExpandHeight="300dp"
        app:ItemsDivider="@color/gray_400"
        app:DividerHeight="0.5dp"/>

</LinearLayout>
(c). view_list_item.xml
?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:paddingTop="4dp"
              android:paddingBottom="4dp"
              android:paddingRight="4dp"
              android:paddingLeft="8dp"
              android:orientation="horizontal"
              app:layout_collapseMode="parallax"
              app:layout_collapseParallaxMultiplier="0.5">

    <ImageView
        android:id="@+id/ImgVw_Letters"
        android:layout_width="32dp"
        android:layout_height="32dp"/>

    <TextView
        android:id="@+id/TxtVw_DisplayName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_gravity="center_vertical"/>

</LinearLayout>
(d). view_no_selection_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:paddingTop="8dp"
              android:paddingBottom="8dp"
              android:paddingRight="4dp"
              android:paddingLeft="8dp"
              android:orientation="horizontal"
              app:layout_collapseMode="parallax"
              app:layout_collapseParallaxMultiplier="0.5">

    <TextView
        android:id="@+id/TxtVw_NoSelection"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_gravity="center_vertical"
        android:text="@string/no_selection"/>
</LinearLayout>

Java Code.

Android apps can be mainly written in Java or Kotlin. These days however there are many frameworks like Flutter also which use languages like Dart.

In this class we are using Java programming language.

We will have these classes in our project.

(a). MainActivity.java

This is our launcher activity as the name suggests. This means it will be the main entry point to our app in that when the user clicks the icon for our app, this activity will get rendered first.

We override a method called onCreate(). Here we will start by inflating our main layout via the setContentView() method.

Our main activity is actually an activity since it's deriving from the AppCompatActivity.

package gr.escsoft.michaelprimez.searchablespinnerexamples; 

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.view.MotionEvent;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.util.ArrayList;

import gr.escsoft.michaelprimez.searchablespinner.SearchableSpinner; 
import gr.escsoft.michaelprimez.searchablespinner.interfaces.IStatusListener; 
import gr.escsoft.michaelprimez.searchablespinner.interfaces.OnItemSelectedListener; 

public class MainActivity extends AppCompatActivity { 

    private SearchableSpinner mSearchableSpinner;
    private SearchableSpinner mSearchableSpinner1;
    private SearchableSpinner mSearchableSpinner2;
    private SearchableSpinner mSearchableSpinner3;
    private SimpleListAdapter mSimpleListAdapter;
    private SimpleArrayListAdapter mSimpleArrayListAdapter;
    private final ArrayList<String> mStrings = new ArrayList<>();

    @Override 
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        initListValues(); 
        mSimpleListAdapter = new SimpleListAdapter(this, mStrings);
        mSimpleArrayListAdapter = new SimpleArrayListAdapter(this, mStrings);

        mSearchableSpinner = (SearchableSpinner) findViewById(R.id.SearchableSpinner);
        mSearchableSpinner.setAdapter(mSimpleArrayListAdapter);
        mSearchableSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
        mSearchableSpinner.setStatusListener(new IStatusListener() {
            @Override 
            public void spinnerIsOpening() { 
                mSearchableSpinner1.hideEdit();
                mSearchableSpinner2.hideEdit();
            } 

            @Override 
            public void spinnerIsClosing() { 

            } 
        }); 

        mSearchableSpinner1 = (SearchableSpinner) findViewById(R.id.SearchableSpinner1);
        mSearchableSpinner1.setAdapter(mSimpleListAdapter);
        mSearchableSpinner1.setOnItemSelectedListener(mOnItemSelectedListener);
        mSearchableSpinner1.setStatusListener(new IStatusListener() {
            @Override 
            public void spinnerIsOpening() { 
                mSearchableSpinner.hideEdit();
                mSearchableSpinner2.hideEdit();
            } 

            @Override 
            public void spinnerIsClosing() { 

            } 
        }); 

        mSearchableSpinner2 = (SearchableSpinner) findViewById(R.id.SearchableSpinner2);
        mSearchableSpinner2.setAdapter(mSimpleListAdapter);
        mSearchableSpinner2.setOnItemSelectedListener(mOnItemSelectedListener);
        mSearchableSpinner2.setStatusListener(new IStatusListener() {
            @Override 
            public void spinnerIsOpening() { 
                mSearchableSpinner.hideEdit();
                mSearchableSpinner1.hideEdit();
            } 

            @Override 
            public void spinnerIsClosing() { 

            } 
        }); 

        mSearchableSpinner3 = (SearchableSpinner) findViewById(R.id.SearchableSpinner3);
        mSearchableSpinner3.setAdapter(mSimpleListAdapter);
        mSearchableSpinner3.setOnItemSelectedListener(mOnItemSelectedListener);
        mSearchableSpinner3.setStatusListener(new IStatusListener() {
            @Override 
            public void spinnerIsOpening() { 
                mSearchableSpinner.hideEdit();
                mSearchableSpinner3.hideEdit();
            } 

            @Override 
            public void spinnerIsClosing() { 

            } 
        }); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) {
        if (!mSearchableSpinner.isInsideSearchEditText(event)) {
            mSearchableSpinner.hideEdit();
        } 
        if (!mSearchableSpinner1.isInsideSearchEditText(event)) {
            mSearchableSpinner1.hideEdit();
        } 
        if (!mSearchableSpinner2.isInsideSearchEditText(event)) {
            mSearchableSpinner2.hideEdit();
        } 
        return super.onTouchEvent(event);
    } 

    private OnItemSelectedListener mOnItemSelectedListener = new OnItemSelectedListener() {
        @Override 
        public void onItemSelected(View view, int position, long id) { 
            Toast.makeText(MainActivity.this, "Item on position " + position + " : " + mSimpleListAdapter.getItem(position) + " Selected", Toast.LENGTH_SHORT).show(); 
        } 

        @Override 
        public void onNothingSelected() { 
            Toast.makeText(MainActivity.this, "Nothing Selected", Toast.LENGTH_SHORT).show(); 
        } 
    }; 

    private void initListValues() { 
        mStrings.add("Brigida Kurz");
        mStrings.add("Tracy Mckim");
        mStrings.add("Iesha Davids");
        mStrings.add("Ozella Provenza");
        mStrings.add("Florentina Carriere");
        mStrings.add("Geri Eiler");
        mStrings.add("Tammara Belgrave");
        mStrings.add("Ashton Ridinger");
        mStrings.add("Jodee Dawkins");
        mStrings.add("Florine Cruzan");
        mStrings.add("Latia Stead");
        mStrings.add("Kai Urbain");
        mStrings.add("Liza Chi");
        mStrings.add("Clayton Laprade");
        mStrings.add("Wilfredo Mooney");
        mStrings.add("Roseline Cain");
        mStrings.add("Chadwick Gauna");
        mStrings.add("Carmela Bourn");
        mStrings.add("Valeri Dedios");
        mStrings.add("Calista Mcneese");
        mStrings.add("Willard Cuccia");
        mStrings.add("Ngan Blakey");
        mStrings.add("Reina Medlen");
        mStrings.add("Fabian Steenbergen");
        mStrings.add("Edmond Pine");
        mStrings.add("Teri Quesada");
        mStrings.add("Vernetta Fulgham");
        mStrings.add("Winnifred Kiefer");
        mStrings.add("Chiquita Lichty");
        mStrings.add("Elna Stiltner");
        mStrings.add("Carly Landon");
        mStrings.add("Hans Morford");
        mStrings.add("Shawanna Kapoor");
        mStrings.add("Thomasina Naron");
        mStrings.add("Melba Massi");
        mStrings.add("Sal Mangano");
        mStrings.add("Mika Weitzel");
        mStrings.add("Phylis France");
        mStrings.add("Illa Winzer");
        mStrings.add("Kristofer Boyden");
        mStrings.add("Idalia Cryan");
        mStrings.add("Jenni Sousa");
        mStrings.add("Eda Forkey");
        mStrings.add("Birgit Rispoli");
        mStrings.add("Janiece Mcguffey");
        mStrings.add("Barton Busick");
        mStrings.add("Gerald Westerman");
        mStrings.add("Shalanda Baran");
        mStrings.add("Margherita Pazos");
        mStrings.add("Yuk Fitts");
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present. 
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will 
        // automatically handle clicks on the Home/Up button, so long 
        // as you specify a parent activity in AndroidManifest.xml. 
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement 
        if (id == R.id.action_reset) {
            mSearchableSpinner.setSelectedItem(0);
            mSearchableSpinner1.setSelectedItem(0);
            mSearchableSpinner2.setSelectedItem(0);
            return true; 
        } 

        return super.onOptionsItemSelected(item);
    } 
} 
(b). SearchableSpinnerApp.java
import android.app.Application;

import com.facebook.stetho.Stetho; 

public class SearchableSpinnerApp extends Application {
    @Override 
    public void onCreate() { 
        super.onCreate(); 
        Stetho.initializeWithDefaults(this);
    } 
} 
(c). SimpleArrayListAdapter.java

The SimpleArrayListAdapter class.

Here's the full code.

package gr.escsoft.michaelprimez.searchablespinnerexamples;

import android.content.Context;
import android.graphics.Color;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;

import java.util.ArrayList;

import gr.escsoft.michaelprimez.revealedittext.tools.UITools;
import gr.escsoft.michaelprimez.searchablespinner.interfaces.ISpinnerSelectedView;

public class SimpleArrayListAdapter extends ArrayAdapter<String> implements Filterable, ISpinnerSelectedView {

    private Context mContext;
    private ArrayList<String> mBackupStrings;
    private ArrayList<String> mStrings;
    private StringFilter mStringFilter = new StringFilter();

    public SimpleArrayListAdapter(Context context, ArrayList<String> strings) {
        super(context, R.layout.view_list_item);
        mContext = context;
        mStrings = strings;
        mBackupStrings = strings;
    }

    @Override
    public int getCount() {
        return mStrings == null ? 0 : mStrings.size() + 1;
    }

    @Override
    public String getItem(int position) {
        if (mStrings != null && position > 0)
            return mStrings.get(position - 1);
        else
            return null;
    }

    @Override
    public long getItemId(int position) {
        if (mStrings == null && position > 0)
            return mStrings.get(position).hashCode();
        else
            return -1;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = null;
        if (position == 0) {
            view = getNoSelectionView();
        } else {
            view = View.inflate(mContext, R.layout.view_list_item, null);
            ImageView letters = (ImageView) view.findViewById(R.id.ImgVw_Letters);
            TextView dispalyName = (TextView) view.findViewById(R.id.TxtVw_DisplayName);
            letters.setImageDrawable(getTextDrawable(mStrings.get(position-1)));
            dispalyName.setText(mStrings.get(position-1));
        }
        return view;
    }

    @Override
    public View getSelectedView(int position) {
        View view = null;
        if (position == 0) {
            view = getNoSelectionView();
        } else {
            view = View.inflate(mContext, R.layout.view_list_item, null);
            ImageView letters = (ImageView) view.findViewById(R.id.ImgVw_Letters);
            TextView dispalyName = (TextView) view.findViewById(R.id.TxtVw_DisplayName);
            letters.setImageDrawable(getTextDrawable(mStrings.get(position-1)));
            dispalyName.setText(mStrings.get(position-1));
        }
        return view;
    }

    @Override
    public View getNoSelectionView() {
        View view = View.inflate(mContext, R.layout.view_list_no_selection_item, null);
        return view;
    }

    private TextDrawable getTextDrawable(String displayName) {
        TextDrawable drawable = null;
        if (!TextUtils.isEmpty(displayName)) {
            int color2 = ColorGenerator.MATERIAL.getColor(displayName);
            drawable = TextDrawable.builder()
                    .beginConfig()
                    .width(UITools.dpToPx(mContext, 32))
                    .height(UITools.dpToPx(mContext, 32))
                    .textColor(Color.WHITE)
                    .toUpperCase()
                    .endConfig()
                    .round()
                    .build(displayName.substring(0, 1), color2);
        } else {
            drawable = TextDrawable.builder()
                    .beginConfig()
                    .width(UITools.dpToPx(mContext, 32))
                    .height(UITools.dpToPx(mContext, 32))
                    .endConfig()
                    .round()
                    .build("?", Color.GRAY);
        }
        return drawable;
    }

    @Override
    public Filter getFilter() {
        return mStringFilter;
    }

    public class StringFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults filterResults = new FilterResults();
            if (TextUtils.isEmpty(constraint)) {
                filterResults.count = mBackupStrings.size();
                filterResults.values = mBackupStrings;
                return filterResults;
            }
            final ArrayList<String> filterStrings = new ArrayList<>();
            for (String text : mBackupStrings) {
                if (text.toLowerCase().contains(constraint)) {
                    filterStrings.add(text);
                }
            }
            filterResults.count = filterStrings.size();
            filterResults.values = filterStrings;
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mStrings = (ArrayList) results.values;
            notifyDataSetChanged();
        }
    }

    private class ItemView {
        public ImageView mImageView;
        public TextView mTextView;
    }

    public enum ItemViewType {
        ITEM, NO_SELECTION_ITEM;
    }
}
(d). SimpleListAdapter.java

The SimpleListAdapter class.

Here's the full code.

package gr.escsoft.michaelprimez.searchablespinnerexamples;

import android.content.Context;
import android.graphics.Color;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator;

import java.util.ArrayList;

import gr.escsoft.michaelprimez.revealedittext.tools.UITools;
import gr.escsoft.michaelprimez.searchablespinner.interfaces.ISpinnerSelectedView;
import gr.escsoft.michaelprimez.searchablespinner.interfaces.OnItemSelectedListener;

public class SimpleListAdapter extends BaseAdapter implements Filterable, ISpinnerSelectedView {

    private Context mContext;
    private ArrayList<String> mBackupStrings;
    private ArrayList<String> mStrings;
    private StringFilter mStringFilter = new StringFilter();

    public SimpleListAdapter(Context context, ArrayList<String> strings) {
        mContext = context;
        mStrings = strings;
        mBackupStrings = strings;
    }

    @Override
    public int getCount() {
        return mStrings == null ? 0 : mStrings.size() + 1;
    }

    @Override
    public Object getItem(int position) {
        if (mStrings != null && position > 0)
            return mStrings.get(position - 1);
        else
            return null;
    }

    @Override
    public long getItemId(int position) {
        if (mStrings == null && position > 0)
            return mStrings.get(position).hashCode();
        else
            return -1;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = null;
        if (position == 0) {
            view = getNoSelectionView();
        } else {
            view = View.inflate(mContext, R.layout.view_list_item, null);
            ImageView letters = (ImageView) view.findViewById(R.id.ImgVw_Letters);
            TextView dispalyName = (TextView) view.findViewById(R.id.TxtVw_DisplayName);
            letters.setImageDrawable(getTextDrawable(mStrings.get(position-1)));
            dispalyName.setText(mStrings.get(position-1));
        }
        return view;
    }

    @Override
    public View getSelectedView(int position) {
        View view = null;
        if (position == 0) {
            view = getNoSelectionView();
        } else {
            view = View.inflate(mContext, R.layout.view_list_item, null);
            ImageView letters = (ImageView) view.findViewById(R.id.ImgVw_Letters);
            TextView dispalyName = (TextView) view.findViewById(R.id.TxtVw_DisplayName);
            letters.setImageDrawable(getTextDrawable(mStrings.get(position-1)));
            dispalyName.setText(mStrings.get(position-1));
        }
        return view;
    }

    @Override
    public View getNoSelectionView() {
        View view = View.inflate(mContext, R.layout.view_list_no_selection_item, null);
        return view;
    }

    private TextDrawable getTextDrawable(String displayName) {
        TextDrawable drawable = null;
        if (!TextUtils.isEmpty(displayName)) {
            int color2 = ColorGenerator.MATERIAL.getColor(displayName);
            drawable = TextDrawable.builder()
                    .beginConfig()
                    .width(UITools.dpToPx(mContext, 32))
                    .height(UITools.dpToPx(mContext, 32))
                    .textColor(Color.WHITE)
                    .toUpperCase()
                    .endConfig()
                    .round()
                    .build(displayName.substring(0, 1), color2);
        } else {
            drawable = TextDrawable.builder()
                    .beginConfig()
                    .width(UITools.dpToPx(mContext, 32))
                    .height(UITools.dpToPx(mContext, 32))
                    .endConfig()
                    .round()
                    .build("?", Color.GRAY);
        }
        return drawable;
    }

    @Override
    public Filter getFilter() {
        return mStringFilter;
    }

    public class StringFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults filterResults = new FilterResults();
            if (TextUtils.isEmpty(constraint)) {
                filterResults.count = mBackupStrings.size();
                filterResults.values = mBackupStrings;
                return filterResults;
            }
            final ArrayList<String> filterStrings = new ArrayList<>();
            for (String text : mBackupStrings) {
                if (text.toLowerCase().contains(constraint)) {
                    filterStrings.add(text);
                }
            }
            filterResults.count = filterStrings.size();
            filterResults.values = filterStrings;
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mStrings = (ArrayList) results.values;
            notifyDataSetChanged();
        }
    }

    private class ItemView {
        public ImageView mImageView;
        public TextView mTextView;
    }

    public enum ItemViewType {
        ITEM, NO_SELECTION_ITEM;
    }
}

Download

Download the project below.

No. Location Link
1. GitHub Direct Download
2. GitHub Browse

Credit to the Original Creator michaelprimez

How to Run

  1. Download the project.
  2. Go over to app folder and edit import it to your android studio.Alternatively you can just copy paste the classes as well as the layouts and maybe other resources into your already created project.
  3. Then edit the app level build/gradle to add our dependency.

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post