Listview with Alphabatical Indexer

Introduction:
    Today I am going to share a sample application in Android which have similar
functionality like Iphone Alphabatical Indexing.

    1. How to display alphabetical index at right side of the ListView.
    2. How to create a ListView displaying list of Tamilnadu States. 
    3. Display corresponding list items by selecting a letter from the alphabet indexer at the right.
demo



Using this code

Step1:
1.Declare fastsearchlistview in xml.

activity_main.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:background="#69C4C9">
<com.kalidoss.listview_section_indexer.FastSearchListView
 android:id="@+id/listview"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerHorizontal="true"
 android:layout_centerVertical="true" />

</RelativeLayout>

Step2:
1.This default class for fast search listview values.

FastSearchListView.java:
package com.kalidoss.listview_section_indexer;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SectionIndexer;

public class FastSearchListView extends ListView {

private Context ctx;

private static int indWidth = 20;
private String[] sections;
private float scaledWidth;
private float sx;
private int indexSize;
private String section;
private boolean showLetter = true;
private Handler listHandler;
public FastSearchListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
ctx = context;
}

public FastSearchListView(Context context, AttributeSet attrs) {
super(context, attrs);
ctx = context;
}

public FastSearchListView(Context context, String keyList) {
super(context);
ctx = context;
}


@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

scaledWidth = indWidth * getSizeInPixel(ctx);
sx = this.getWidth() - this.getPaddingRight() - scaledWidth;

Paint p = new Paint();
p.setColor(Color.WHITE);
p.setAlpha(100);

canvas.drawRect(sxthis.getPaddingTop(), sx + scaledWidth,
this.getHeight() - this.getPaddingBottom(), p);
indexSize = (this.getHeight() - this.getPaddingTop() - getPaddingBottom())
sections.length;

Paint textPaint = new Paint();
textPaint.setColor(Color.DKGRAY);
textPaint.setTextSize(scaledWidth / 2);

for (int i = 0; i < sections.length; i++)
canvas.drawText(sections[i].toUpperCase(),
sx + textPaint.getTextSize() / 2, getPaddingTop()
indexSize * (i + 1), textPaint);
// We draw the letter in the middle
if (showLetter & section != null && !section.equals("")) {
Paint textPaint2 = new Paint();
textPaint2.setColor(Color.DKGRAY);
textPaint2.setTextSize(2 * indWidth);
canvas.drawText(section.toUpperCase(), getWidth() / 2, getHeight() / 2, textPaint2);
}
}

private static float getSizeInPixel(Context ctx) {
return ctx.getResources().getDisplayMetrics().density;
}

@Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(adapter);
if (adapter instanceof SectionIndexer)
sections = (String[]) ((SectionIndexer) adapter).getSections();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
if (x < sx)
return super.onTouchEvent(event);
else {
// We touched the index bar
float y = event.getY() - this.getPaddingTop() - getPaddingBottom();
int currentPosition = (int) Math.floor(y / indexSize);
section = sections[currentPosition];
this.setSelection(((SectionIndexer) getAdapter())
.getPositionForSection(currentPosition));
}
break;
}
case MotionEvent.ACTION_MOVE: {
if (x < sx)
return super.onTouchEvent(event);
else {
float y = event.getY();
int currentPosition = (int) Math.floor(y / indexSize);
section = sections[currentPosition];
this.setSelection(((SectionIndexer) getAdapter())
.getPositionForSection(currentPosition));

}
break;

}
case MotionEvent.ACTION_UP: {
listHandler = new ListHandler();
listHandler.sendEmptyMessageDelayed(0, 30 * 1000);
break;
}
}
return true;
}

private class ListHandler extends Handler {

@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
showLetter = false;
FastSearchListView.this.invalidate();
}
}
}

Step2:
1.Declare FastSearckListView us a listview in MainActivity.

MainActivity.java
package com.kalidoss.listview_section_indexer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<String> countries = new ArrayList<String>();
countries.add("Chennai");
countries.add("Coimbatore");
countries.add("Thiruvarur");
countries.add("Thirupur");
countries.add("Ariyalur");
countries.add("Virudhunagar");
countries.add("Villupuram");
countries.add("Vellore");
countries.add("Thiruvannamalai");
countries.add("Thiruvallur");
countries.add("Thirunelveli");
countries.add("Trichy");
countries.add("Thoothukudi");
countries.add("Nilgiris");
countries.add("Theni");
countries.add("Thanjavur");
countries.add("Sivagangai");
countries.add("Salem");
countries.add("Ramanathapuram");
countries.add("Pudukottai");
countries.add("Perambalur");
countries.add("Namakkal");
countries.add("Nagapattinam");
countries.add("Madurai");
countries.add("Krishnagiri");
countries.add("Karur");
countries.add("Kanyakumari");
countries.add("Kanchipuram");
countries.add("Erode");
countries.add("Dindigul");
countries.add("Dharmapuri");
countries.add("Cuddalore");
Collections.sort(countries);
FastSearchListView listView = (FastSearchListView) findViewById(R.id.listview);
SimpleAdapter sa = new SimpleAdapter(countries, this);
listView.setAdapter(sa);
//listView.setFastScrollEnabled(true);
}

}

Step3:
1.Lisiview adapter.

SimpleAdapter.java
package com.kalidoss.listview_section_indexer;

import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.SectionIndexer;
import android.widget.TextView;

public class SimpleAdapter extends ArrayAdapter<String> implements SectionIndexer {
private List<String> itemList;
private Context context;
private static String sections = "abcdefghilmnopqrstuvz";
public SimpleAdapter(List<String> itemList, Context ctx) {
super(ctx, android.R.layout.simple_list_item_1, itemList);
this.itemList = itemList;
this.context = ctx;
}
public int getCount() {
return itemList.size();
}

public String getItem(int position) {
return itemList.get(position);
}

public long getItemId(int position) {
return itemList.get(position).hashCode();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(android.R.layout.simple_list_item_1null);
}
TextView text = (TextView) v.findViewById(android.R.id.text1);
text.setText(itemList.get(position));
return v;
}

@Override
public int getPositionForSection(int section) {
Log.d("ListView""Get position for section");
for (int i=0; i < this.getCount(); i++) {
String item = this.getItem(i).toLowerCase();
if (item.charAt(0) == sections.charAt(section))
return i;
}
return 0;
}

@Override
public int getSectionForPosition(int arg0) {
Log.d("ListView""Get section");
return 0;
}

@Override
public Object[] getSections() {
Log.d("ListView""Get sections");
String[] sectionsArr = new String[sections.length()];
for (int i=0; i < sections.length(); i++)
sectionsArr[i] = "" + sections.charAt(i);
return sectionsArr;
}

}


Happy coding...

Previous
Next Post »

1 comments:

Write comments
Anonymous
AUTHOR
January 29, 2015 at 8:20 AM delete

The code works fine but there is a problem while implementing the onItemClick for the list view. The onTouchEvent doesn't allow the onItemClickListener to work.

Reply
avatar