Tuesday, May 28, 2013

Android ListView Indexer



Below I have Declared all code , java classes, xml and Manifiest file also:- 



1:- SideIndex.java file

package andriod.abhi.sideindex;

import java.util.ArrayList;
import java.util.Arrays;

import de.helloandroid.sideindex.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;

public class SideIndex extends Activity
{
private GestureDetector mGestureDetector;

// x and y coordinates within our side index
private static float sideIndexX;
private static float sideIndexY;

// height of side index
private int sideIndexHeight;

// number of items in the side index
private int indexListSize;

// list with items for side index
private ArrayList<Object[]> indexList = null;

// an array with countries to display in the list
static String[] COUNTRY= new String[]

"British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso",
"Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada",
"Cape Verde", "Cayman Islands", "Central African Republic", "Chad",
"Chile", "China", "Reunion", "Romania", "Russia", "Rwanda",
"Sqo Tome and Principe", "Saint Helena", "Saint Kitts and Nevis",
"Saint Lucia", "Saint Pierre and Miquelon", "Belize", "Benin",
"Bermuda", "Bhutan", "Bolivia", "Christmas Island",
"Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
"Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus",
"Czech Republic", "Democratic Republic of the Congo", "Denmark",
"Djibouti", "Dominica", "Dominican Republic",
"Former Yugoslav Republic of Macedonia", "France", "French Guiana",
"French Polynesia", "Macau", "Madagascar", "Malawi", "Malaysia",
"Maldives", "Mali", "Malta", "Marshall Islands", "Yemen",
"Yugoslavia", "Zambia", "Zimbabwe" };

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

// Sortin array
Arrays.sort(COUNTRY);

final ListView lv1 = (ListView) findViewById(R.id.ListView);
lv1.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, COUNTRY));
mGestureDetector = new GestureDetector(this, new SideIndexGestureListener());
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
if (mGestureDetector.onTouchEvent(event))
{
return true;
} else
{
return false;
}
}

private ArrayList<Object[]> createIndex(String[] strArr)
{
ArrayList<Object[]> tmpIndexList = new ArrayList<Object[]>();
Object[] tmpIndexItem = null;

int tmpPos = 0;
String tmpLetter = "";
String currentLetter = null;
String strItem = null;

for (int j = 0; j < strArr.length; j++)
{
strItem = strArr[j];
currentLetter = strItem.substring(0, 1);

// every time new letters comes
// save it to index list
if (!currentLetter.equals(tmpLetter))
{
tmpIndexItem = new Object[3];
tmpIndexItem[0] = tmpLetter;
tmpIndexItem[1] = tmpPos - 1;
tmpIndexItem[2] = j - 1;

tmpLetter = currentLetter;
tmpPos = j + 1;

tmpIndexList.add(tmpIndexItem);
}
}

// save also last letter
tmpIndexItem = new Object[3];
tmpIndexItem[0] = tmpLetter;
tmpIndexItem[1] = tmpPos - 1;
tmpIndexItem[2] = strArr.length - 1;
tmpIndexList.add(tmpIndexItem);

// and remove first temporary empty entry
if (tmpIndexList != null && tmpIndexList.size() > 0)
{
tmpIndexList.remove(0);
}

return tmpIndexList;
}

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);

final ListView listView = (ListView) findViewById(R.id.ListView);
LinearLayout sideIndex = (LinearLayout) findViewById(R.id.sideIndex);
sideIndexHeight = sideIndex.getHeight();
sideIndex.removeAllViews();


TextView tmpTV = null;

// we'll create the index list
indexList = createIndex(COUNTRY);


indexListSize = indexList.size();

// maximal number of item, which could be displayed
int indexMaxSize = (int) Math.floor(sideIndex.getHeight() / 20);

int tmpIndexListSize = indexListSize;

// handling that case when indexListSize > indexMaxSize
while (tmpIndexListSize > indexMaxSize)
{
tmpIndexListSize = tmpIndexListSize / 2;
}

// computing delta (only a part of items will be displayed to save a
// place)
double delta = indexListSize / tmpIndexListSize;

String tmpLetter = null;
Object[] tmpIndexItem = null;

// show every m-th letter
for (double i = 1; i <= indexListSize; i = i + delta)
{
tmpIndexItem = indexList.get((int) i - 1);
tmpLetter = tmpIndexItem[0].toString();
tmpTV = new TextView(this);
tmpTV.setText(tmpLetter);
tmpTV.setGravity(Gravity.CENTER);
tmpTV.setTextSize(20);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1);
tmpTV.setLayoutParams(params);
sideIndex.addView(tmpTV);
}

// and set a touch listener for it
sideIndex.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
// now you know coordinates of touch
sideIndexX = event.getX();
sideIndexY = event.getY();

// and can display a proper item it country list
displayListItem();

return false;
}
});
}

class SideIndexGestureListener extends
GestureDetector.SimpleOnGestureListener
{
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY)
{
// we know already coordinates of first touch
// we know as well a scroll distance
sideIndexX = sideIndexX - distanceX;
sideIndexY = sideIndexY - distanceY;

// when the user scrolls within our side index
// we can show for every position in it a proper
// item in the country list
if (sideIndexX >= 0 && sideIndexY >= 0)
{
displayListItem();
}

return super.onScroll(e1, e2, distanceX, distanceY);
}
}

public void displayListItem()
{
// compute number of pixels for every side index item
double pixelPerIndexItem = (double) sideIndexHeight / indexListSize;

// compute the item index for given event position belongs to
int itemPosition = (int) (sideIndexY / pixelPerIndexItem);

// compute minimal position for the item in the list
int minPosition = (int) (itemPosition * pixelPerIndexItem);

// get the item (we can do it since we know item index)
Object[] indexItem = indexList.get(itemPosition);

// and compute the proper item in the country list
int indexMin = Integer.parseInt(indexItem[1].toString());
int indexMax = Integer.parseInt(indexItem[2].toString());
int indexDelta = Math.max(1, indexMax - indexMin);

double pixelPerSubitem = pixelPerIndexItem / indexDelta;
int subitemPosition = (int) (indexMin + (sideIndexY - minPosition) / pixelPerSubitem);

ListView listView = (ListView) findViewById(R.id.ListView);
listView.setSelection(subitemPosition);
}
}

------------------------------------------------------------------------------------------------------------------------------

2:-  main.xml




<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" 
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout 
android:orientation="horizontal"
android:layout_width="fill_parent" 

android:layout_height="wrap_content">
<ListView 
android:id="@+id/ListView" 
android:layout_width="0dp"
android:fastScrollEnabled="true"
android:layout_height="wrap_content" 
android:layout_weight="1">
</ListView>
<LinearLayout 
android:orientation="vertical"
android:background="#FFF" 
android:id="@+id/sideIndex"
android:layout_width="40dip" 
android:layout_height="fill_parent"
android:gravity="center_horizontal">
</LinearLayout>
</LinearLayout>
</LinearLayout>

------------------------------------------------------------------------------------------------------------------------------



3:- Manifiest file:- 



 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="de.helloandroid.sideindex"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name="andriod.abhi.sideindex.SideIndex"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="3" />

</manifest> 

No comments:

Post a Comment