title: how to add fast scroll and alphabetical section index in listview
body: <p>In details, I am looking for an example exactly like below image. I got a good example in this link <a href="https://github.com/woozzu/IndexableListView" rel="nofollow noreferrer">https://github.com/woozzu/IndexableListView</a>. Its works fine as my requirement.But problem when i implementing to my project it is showing error in list view.  below is my code plz help me. i am new to this topic. Thank you in advance!</p>
  
  <p>looking for:</p>
  
  <p><img src="https://i.stack.imgur.com/lFqiE.png" alt="screenshot of desired UI"><br>
  here is my code below plz say my mistake..</p>
  
  <p>MainActivity .java</p>
  
  <pre><code>public class MainActivity extends Activity implements     SearchView.OnQueryTextListener,SearchView.OnCloseListener {
  
  private ListView listView;
  private SearchView search;
  EfficientAdapter objectAdapter;
  EfficientAdapter2 objectAdapter1;
  int textlength=0;
  private CheckBox checkStat, checkRoutine, checkTat;
   private GestureDetector mGestureDetector;
  private ArrayList&lt;CountriesList&gt; elements;
  
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
     setContentView(R.layout.homempleb);
     Log.i("scan"," txtScanResult ");
  
  
  //Arrays.sort(CountriesList.name);
  ActionItem nextItem     = new ActionItem(); 
  final QuickAction quickAction = new QuickAction(this, QuickAction.VERTICAL);
  quickAction.addActionItem(nextItem);
  quickAction.setOnDismissListener(new QuickAction.OnDismissListener() {          
      @Override
      public void onDismiss() {
          Toast.makeText(getApplicationContext(), "Dismissed", Toast.LENGTH_SHORT).show();
      }
  });
  
  
  search = (SearchView) findViewById(R.id.searchView1);
  search.setIconifiedByDefault(false);    
  search.setOnQueryTextListener(this);
  search.setOnCloseListener(this);
  search.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
          quickAction.show(v);
      }
  });
  checkStat  =  (CheckBox) findViewById(R.id.checkBoxStat);
  checkRoutine  =  (CheckBox) findViewById(R.id.checkBoxRoutine);
  checkTat  =  (CheckBox) findViewById(R.id.checkBoxTat);
  checkStat.setOnClickListener(new OnClickListener() {             
        @Override
        public void onClick(View v) {                  
            if (((CheckBox) v).isChecked()) {
                checkStat.setChecked(true);
                Toast.makeText(MainActivity.this, "STAT", Toast.LENGTH_SHORT).show();
                checkRoutine.setChecked(false);
                checkTat.setChecked(false);                 
                  } 
        }
      });
  checkRoutine.setOnClickListener(new OnClickListener() {          
        @Override
        public void onClick(View v) {                  
            if (((CheckBox) v).isChecked()) {
                checkRoutine.setChecked(true);
                Toast.makeText(MainActivity.this, "ROUTINE", Toast.LENGTH_SHORT).show();
                checkStat.setChecked(false);
                checkTat.setChecked(false);                 
                  } 
        }
      });
  checkTat.setOnClickListener(new OnClickListener() {          
        @Override
        public void onClick(View v) {                  
            if (((CheckBox) v).isChecked()) {
                checkTat.setChecked(true);
                Toast.makeText(MainActivity.this, "TAT Effeciency", Toast.LENGTH_SHORT).show();
                checkRoutine.setChecked(false);
                checkStat.setChecked(false);                
                  } 
        }
      });
  
  
  
  
  listView = (ListView) findViewById(R.id.homelistView);
  listView.setTextFilterEnabled(true);
  listView.setFastScrollEnabled(true);  
  objectAdapter = new EfficientAdapter(this, elements );
  listView.setAdapter(objectAdapter);
  
  Button refreshButton= (Button)findViewById(R.id.refreshButton);
   refreshButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
          objectAdapter1 = new EfficientAdapter2(MainActivity.this);
  //       objectAdapter = new EfficientAdapter(MainActivity.this);// adapter with new data
         listView.setAdapter(objectAdapter1);
  
         Log.i("notifyDataSetChanged", "data updated");
         objectAdapter1.notifyDataSetChanged();
  
      }
  });  
  
  }
  
  @Override
  public boolean onClose() {
      return false;
  }
  
  @Override
  public boolean onQueryTextChange(String newText) {
      return false;
  }
  
  @Override
  public boolean onQueryTextSubmit(String query) {
      return false;
  }
  }
  </code></pre>
  
  <p>EfficientAdapter.java</p>
  
  <pre><code>  public class EfficientAdapter extends BaseAdapter implements SectionIndexer {
  
  private AlphabetIndexer alphaIndexer;
  
  private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  
     private LayoutInflater mInflater;
      private Context context;
  
    public EfficientAdapter(Context context, ArrayList&lt;CountriesList&gt; elements) {
  mInflater = LayoutInflater.from(context);
  
  
  
  this.context=context;
  
     }
  
  
  public int getCount() {
  return CountriesList.name.length;
      }
  
         public Object getItem(int position) {
  
  return position;
       }
  
             public long getItemId(int position) {
  return position;
           }
  
        public View getView(int position, View convertView, ViewGroup parent) {
       ViewHolder holder;
     if (convertView == null) {
      convertView = mInflater.inflate(R.layout.homemplebrowview, null);
      holder = new ViewHolder();
      holder.text1 = (TextView) convertView
              .findViewById(R.id.name);
      holder.text2 = (TextView) convertView
              .findViewById(R.id.mrn);
      holder.text3 = (TextView) convertView
              .findViewById(R.id.date);
      holder.text4 = (TextView) convertView
              .findViewById(R.id.age);
      holder.text5 = (TextView) convertView
              .findViewById(R.id.gender);
      holder.text6 = (TextView) convertView
              .findViewById(R.id.wardno);
      holder.text7 = (TextView) convertView
              .findViewById(R.id.roomno);
      holder.text8 = (TextView) convertView
              .findViewById(R.id.bedno);                  
      holder.btnList = (Button)convertView.findViewById(R.id.listbutton);
           //   holder.btnList.setOnClickListener(this);
  
      holder.btnList.setOnClickListener(new OnClickListener() {
  
          @Override
          public void onClick(View v) {                       
              Intent next=new Intent(context, SeviceDetails.class);
              context.startActivity(next);
          }
      });
  
  
      convertView.setTag(holder);
  } else {
      holder = (ViewHolder) convertView.getTag();
  }
  
  holder.text1.setText(CountriesList.name[position]);
  holder.text2.setText(CountriesList.mrn[position]);
  holder.text3.setText(CountriesList.actualstart[position]);
  holder.text4.setText(CountriesList.age[position]);
  holder.text5.setText(CountriesList.gender[position]);
  holder.text6.setText(CountriesList.wardNo[position]);
  holder.text7.setText(CountriesList.roomNo[position]);
  holder.text8.setText(CountriesList.bedNo[position]);
  
  return convertView;
        }
  
  
      static class ViewHolder {
  public Button btnList;
  public TextView text8;
  public TextView text7;
  public TextView text6;
  public TextView text5;
  public TextView text4;
  public TextView text1;
  public TextView text2;
  public TextView text3;
       }
  
           @Override
      public void notifyDataSetChanged()
        {
      super.notifyDataSetChanged();
           }
  
  
          @Override
            public int getPositionForSection(int section) {
  // If there is no item for current section, previous section will be selected
  for (int i = section; i &gt;= 0; i--) {
      for (int j = 0; j &lt; getCount(); j++) {
          if (i == 0) {
              // For numeric section
              for (int k = 0; k &lt;= 9; k++) {
              //  if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(k)))
                      return j;
              }
          } else {
          //  if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(mSections.charAt(i))))
                  return j;
          }
      }
  }
  return 0;
      }
  
  
     @Override
             public int getSectionForPosition(int position) {
  return 0;
        }
  
  
           @Override
     public Object[] getSections() {
  String[] sections = new String[mSections.length()];
  for (int i = 0; i &lt; mSections.length(); i++)
      sections[i] = String.valueOf(mSections.charAt(i));
  return sections;
        }
  
        }
  </code></pre>
  
  <p>IndexableListView.java</p>
  
  <pre><code>  public class IndexableListView extends ListView {
  
  private boolean mIsFastScrollEnabled = false;
  private IndexScroller mScroller = null;
  private GestureDetector mGestureDetector = null;
  
  public IndexableListView(Context context) {
      super(context);
  }
  
  public IndexableListView(Context context, AttributeSet attrs) {
      super(context, attrs);
  }
  
  public IndexableListView(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
  }
  
  @Override
  public boolean isFastScrollEnabled() {
      return mIsFastScrollEnabled;
  }
  
  @Override
  public void setFastScrollEnabled(boolean enabled) {
      mIsFastScrollEnabled = enabled;
      if (mIsFastScrollEnabled) {
          if (mScroller == null)
              mScroller = new IndexScroller(getContext(), this);
      } else {
          if (mScroller != null) {
              mScroller.hide();
              mScroller = null;
          }
      }
  }
  
  @Override
  public void draw(Canvas canvas) {
      super.draw(canvas);
  
      // Overlay index bar
      if (mScroller != null)
          mScroller.draw(canvas);
  }
  
  @Override
  public boolean onTouchEvent(MotionEvent ev) {
      // Intercept ListView's touch event
      if (mScroller != null &amp;&amp; mScroller.onTouchEvent(ev))
          return true;
  
      if (mGestureDetector == null) {
          mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
  
              @Override
              public boolean onFling(MotionEvent e1, MotionEvent e2,
                      float velocityX, float velocityY) {
                  // If fling happens, index bar shows
                  mScroller.show();
                  return super.onFling(e1, e2, velocityX, velocityY);
              }
  
          });
      }
      mGestureDetector.onTouchEvent(ev);
  
      return super.onTouchEvent(ev);
  }
  
  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
      return true;
  }
  
  @Override
  public void setAdapter(ListAdapter adapter) {
      super.setAdapter(adapter);
      if (mScroller != null)
          mScroller.setAdapter(adapter);
  }
  
  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
      super.onSizeChanged(w, h, oldw, oldh);
      if (mScroller != null)
          mScroller.onSizeChanged(w, h, oldw, oldh);
  }
  
  }
  </code></pre>
  
  <p>StringMatcher.java</p>
  
  <pre><code> public class StringMatcher {
  
  
  public static boolean match(String value, String keyword) {
      if (value == null || keyword == null)
          return false;
      if (keyword.length() &gt; value.length())
          return false;
  
      int i = 0, j = 0;
      do {
          if (isKorean(value.charAt(i)) &amp;&amp; isInitialSound(keyword.charAt(j))) {
          } else {
              if (keyword.charAt(j) == value.charAt(i)) {
                  i++;
                  j++;
              } else if (j &gt; 0)
                  break;
              else
                  i++;
          }
      } while (i &lt; value.length() &amp;&amp; j &lt; keyword.length());
  
      return (j == keyword.length())? true : false;
  }
  
  private static boolean isKorean(char c) {
      return false;
  }
  
  private static boolean isInitialSound(char c) {
      return false;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>IndexScroller.java</p>
  
  <pre><code>public class IndexScroller {
  
  
  
  private static final int STATE_HIDDEN = 0;
  private static final int STATE_SHOWING = 1;
  private static final int STATE_SHOWN = 2;
  private static final int STATE_HIDING = 3;
  
  public IndexScroller(Context context, ListView lv) {
      mDensity = context.getResources().getDisplayMetrics().density;
      mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
      mListView = lv;
      setAdapter(mListView.getAdapter());
  
      mIndexbarWidth = 20 * mDensity;
      mIndexbarMargin = 10 * mDensity;
      mPreviewPadding = 5 * mDensity;
  }
  
  public void draw(Canvas canvas) {
      if (mState == STATE_HIDDEN)
          return;
  
      // mAlphaRate determines the rate of opacity
      Paint indexbarPaint = new Paint();
      indexbarPaint.setColor(Color.BLACK);
      indexbarPaint.setAlpha((int) (64 * mAlphaRate));
      indexbarPaint.setAntiAlias(true);
      canvas.drawRoundRect(mIndexbarRect, 5 * mDensity, 5 * mDensity, indexbarPaint);
  
      if (mSections != null &amp;&amp; mSections.length &gt; 0) {
          // Preview is shown when mCurrentSection is set
          if (mCurrentSection &gt;= 0) {
              Paint previewPaint = new Paint();
              previewPaint.setColor(Color.BLACK);
              previewPaint.setAlpha(96);
              previewPaint.setAntiAlias(true);
              previewPaint.setShadowLayer(3, 0, 0, Color.argb(64, 0, 0, 0));
  
              Paint previewTextPaint = new Paint();
              previewTextPaint.setColor(Color.WHITE);
              previewTextPaint.setAntiAlias(true);
              previewTextPaint.setTextSize(50 * mScaledDensity);
  
              float previewTextWidth = previewTextPaint.measureText(mSections[mCurrentSection]);
              float previewSize = 2 * mPreviewPadding + previewTextPaint.descent() - previewTextPaint.ascent();
              RectF previewRect = new RectF((mListViewWidth - previewSize) / 2
                      , (mListViewHeight - previewSize) / 2
                      , (mListViewWidth - previewSize) / 2 + previewSize
                      , (mListViewHeight - previewSize) / 2 + previewSize);
  
              canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity, previewPaint);
              canvas.drawText(mSections[mCurrentSection], previewRect.left + (previewSize - previewTextWidth) / 2 - 1
                      , previewRect.top + mPreviewPadding - previewTextPaint.ascent() + 1, previewTextPaint);
          }
  
          Paint indexPaint = new Paint();
          indexPaint.setColor(Color.WHITE);
          indexPaint.setAlpha((int) (255 * mAlphaRate));
          indexPaint.setAntiAlias(true);
          indexPaint.setTextSize(12 * mScaledDensity);
  
          float sectionHeight = (mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length;
          float paddingTop = (sectionHeight - (indexPaint.descent() - indexPaint.ascent())) / 2;
          for (int i = 0; i &lt; mSections.length; i++) {
              float paddingLeft = (mIndexbarWidth - indexPaint.measureText(mSections[i])) / 2;
              canvas.drawText(mSections[i], mIndexbarRect.left + paddingLeft
                      , mIndexbarRect.top + mIndexbarMargin + sectionHeight * i + paddingTop - indexPaint.ascent(), indexPaint);
          }
      }
  }
  
  public boolean onTouchEvent(MotionEvent ev) {
      switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
          // If down event occurs inside index bar region, start indexing
          if (mState != STATE_HIDDEN &amp;&amp; contains(ev.getX(), ev.getY())) {
              setState(STATE_SHOWN);
  
              // It demonstrates that the motion event started from index bar
              mIsIndexing = true;
              // Determine which section the point is in, and move the list to that section
              mCurrentSection = getSectionByPoint(ev.getY());
              mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
              return true;
          }
          break;
      case MotionEvent.ACTION_MOVE:
          if (mIsIndexing) {
              // If this event moves inside index bar
              if (contains(ev.getX(), ev.getY())) {
                  // Determine which section the point is in, and move the list to that section
                  mCurrentSection = getSectionByPoint(ev.getY());
                  mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
              }
              return true;
          }
          break;
      case MotionEvent.ACTION_UP:
          if (mIsIndexing) {
              mIsIndexing = false;
              mCurrentSection = -1;
          }
          if (mState == STATE_SHOWN)
              setState(STATE_HIDING);
          break;
      }
      return false;
  }
  
  public void onSizeChanged(int w, int h, int oldw, int oldh) {
      mListViewWidth = w;
      mListViewHeight = h;
      mIndexbarRect = new RectF(w - mIndexbarMargin - mIndexbarWidth
              , mIndexbarMargin
              , w - mIndexbarMargin
              , h - mIndexbarMargin);
  }
  
  public void show() {
      if (mState == STATE_HIDDEN)
          setState(STATE_SHOWING);
      else if (mState == STATE_HIDING)
          setState(STATE_HIDING);
  }
  
  public void hide() {
      if (mState == STATE_SHOWN)
          setState(STATE_HIDING);
  }
  
  public void setAdapter(Adapter adapter) {
      if (adapter instanceof SectionIndexer) {
          mIndexer = (SectionIndexer) adapter;
          mSections = (String[]) mIndexer.getSections();
      }
  }
  
  private void setState(int state) {
      if (state &lt; STATE_HIDDEN || state &gt; STATE_HIDING)
          return;
  
      mState = state;
      switch (mState) {
      case STATE_HIDDEN:
          // Cancel any fade effect
          mHandler.removeMessages(0);
          break;
      case STATE_SHOWING:
          // Start to fade in
          mAlphaRate = 0;
          fade(0);
          break;
      case STATE_SHOWN:
          // Cancel any fade effect
          mHandler.removeMessages(0);
          break;
      case STATE_HIDING:
          // Start to fade out after three seconds
          mAlphaRate = 1;
          fade(3000);
          break;
      }
  }
  
  private boolean contains(float x, float y) {
      // Determine if the point is in index bar region, which includes the right margin of the bar
      return (x &gt;= mIndexbarRect.left &amp;&amp; y &gt;= mIndexbarRect.top &amp;&amp; y &lt;= mIndexbarRect.top + mIndexbarRect.height());
  }
  
  private int getSectionByPoint(float y) {
      if (mSections == null || mSections.length == 0)
          return 0;
      if (y &lt; mIndexbarRect.top + mIndexbarMargin)
          return 0;
      if (y &gt;= mIndexbarRect.top + mIndexbarRect.height() - mIndexbarMargin)
          return mSections.length - 1;
      return (int) ((y - mIndexbarRect.top - mIndexbarMargin) / ((mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length));
  }
  
  private void fade(long delay) {
      mHandler.removeMessages(0);
      mHandler.sendEmptyMessageAtTime(0, SystemClock.uptimeMillis() + delay);
  }
  
  private Handler mHandler = new Handler() {
  
      @Override
      public void handleMessage(Message msg) {
          super.handleMessage(msg);
  
          switch (mState) {
          case STATE_SHOWING:
              // Fade in effect
              mAlphaRate += (1 - mAlphaRate) * 0.2;
              if (mAlphaRate &gt; 0.9) {
                  mAlphaRate = 1;
                  setState(STATE_SHOWN);
              }
  
              mListView.invalidate();
              fade(10);
              break;
          case STATE_SHOWN:
              // If no action, hide automatically
              setState(STATE_HIDING);
              break;
          case STATE_HIDING:
              // Fade out effect
              mAlphaRate -= mAlphaRate * 0.2;
              if (mAlphaRate &lt; 0.1) {
                  mAlphaRate = 0;
                  setState(STATE_HIDDEN);
              }
  
              mListView.invalidate();
              fade(10);
              break;
          }
      }
  
  };
   }
  </code></pre>
  
  <p>if i add this it works code in mainactivity
        listView = (ListView) findViewById(R.id.homelistView); </p>