在android开发中经常用到列表字母索引与过滤检索,特别是一些基于LBS的应用;
大众点评,点行,酒店达人等中,你都是看到列表字母索引与过滤检索的影子。下面把主要实现类贴出来~~,为了方便大家,源码已经打包并调试过,稍微修改下就可以在项目中使用!代码中有什么我写的不明的地方,给我留言。
 
 
 
android开发实例02:列表字母索引与过滤检索_androidandroid开发实例02:列表字母索引与过滤检索_字母索引_02
 
package com.Johnson.index;

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
*    
* 城市选择 activity
*    
* @author Johnson
*    
*/

public class CitySelectActivity extends Activity implements
    ListView.OnScrollListener {

  // 城市选择

  private ListView listView;
  private ArrayList<City> listBasicData = new ArrayList<City>();// 存放原始数据;
  private ArrayList<City> list = new ArrayList<City>();// 存放临时数据
  private LayoutInflater mInflater;
  private RemoveWindow mRemoveWindow = new RemoveWindow();
  private WindowManager mWindowManager;
  private TextView mDialogText;
  private boolean mShowing;
  private boolean mReady;
  private String mPrevLetter = "";
  private EditText filterEdit;
  Handler mHandler = new Handler();

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
                //原始数据
    listBasicData = City.getCityList();
    
    //初始化显示数据加入字幕索引item
    initShowData();
    this.setContentView(R.layout.city_select);
    mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    listView = (ListView) findViewById(R.id.list_view);
    final myAdapter adapter = new myAdapter();
    listView.setAdapter(adapter);
    listView.setItemsCanFocus(false);
    listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);// 设置单选模型
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View view,
          int position, long id) {
        
      Toast.makeText(getApplicationContext(), list.get(position).getCityName(), Toast.LENGTH_SHORT).show();
        
      }
    });

    filterEdit = (EditText) findViewById(R.id.edit_filter);
    filterEdit.addTextChangedListener(new TextWatcher() {
      public void onTextChanged(CharSequence s, int start, int before,
          int count) {
      }

      public void beforeTextChanged(CharSequence s, int start, int count,
          int after) {
      }

      public void afterTextChanged(Editable s) {
    
        final String txt = s.toString().toLowerCase();
        if (list != null) {
          list.clear();

          if (listBasicData != null && listBasicData.size() > 0) {
            for (City mCity : listBasicData) {

              String pinyin = mCity.getCityPinyin();
              String name = mCity.getCityName();
              if (pinyin.startsWith(txt)
                  || pinyin.startsWith(txt.toLowerCase())
                  || pinyin.startsWith(txt.toUpperCase())
                  || (name.indexOf(txt) != -1)) {
                list.add(mCity);
              }
            }
            if ("".equals(txt)) {
              //当字母过滤框内容为空重新初始化数据
              initShowData();
            }

            if ("".equals(txt)) {

              mReady = true;
            } else {
            
              mReady = false;
            }

            // List数据变化时, 刷新Dialog
            // dialog.notifyDataSetChanged();
            adapter.notifyDataSetChanged();
          }
        }
      }
    });

    initIndexTextView();
  }



  @Override
  public void onScroll(AbsListView view, int firstVisibleItem,
      int visibleItemCount, int totalItemCount) {
    int visibleItemIndex = firstVisibleItem;
    
    
    
    // int visibleItemIndex = firstVisibleItem + (visibleItemCount / 2 - 1);
    
    
    if (mReady) {

      City city = (City) list.get(visibleItemIndex);

      String firstLetter = city.getCityPinyin();
      System.out.println("@" + firstLetter);

      if (firstLetter.equals("-")) {
        firstLetter = firstLetter.substring(1, 2);
      } else {
        firstLetter = firstLetter.substring(0, 1);
      }

      if (!mShowing && firstLetter.equals(mPrevLetter)) {

        mShowing = true;
        mDialogText.setVisibility(View.VISIBLE);
      }

      mDialogText.setTextSize(40);
      mDialogText.setText(firstLetter);
      mHandler.removeCallbacks(mRemoveWindow);
      mHandler.postDelayed(mRemoveWindow, 1000);
      mPrevLetter = firstLetter;
    }
  }

  @Override
  public void onScrollStateChanged(AbsListView arg0, int arg1) {
    // TODO Auto-generated method stub

  }

  private void removeWindow() {

    if (mShowing) {
      mShowing = false;
      mDialogText.setVisibility(View.INVISIBLE);
    }
  }

  private final class RemoveWindow implements Runnable {
    public void run() {
      removeWindow();
    }
  }

  @Override
  protected void onResume() {
    super.onResume();
    mReady = true;
  }

  @Override
  protected void onPause() {
    super.onPause();
    removeWindow();
    mReady = false;
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    if (mWindowManager != null) {
      mWindowManager.removeView(mDialogText);
    }

    mReady = false;
  }

  class myAdapter extends BaseAdapter {

    View convertView;

    City city;

    @Override
    public boolean isEnabled(int position) {

      if (city != null) {
        return !city.getCityName().startsWith("-");
      } else {
        return true;
      }

    }

    @Override
    public int getCount() {
      // TODO Auto-generated method stub
      return list.size();
    }

    @Override
    public Object getItem(int position) {
      // TODO Auto-generated method stub
      return list.get(position);
    }

    @Override
    public long getItemId(int position) {
      // TODO Auto-generated method stub
      return position;
    }

    @Override
    public View getView(int position, View convertVie, ViewGroup arg2) {
      // TODO Auto-generated method stub
      convertView = convertVie;
      TextView tv;

      city = (City) list.get(position);

      if (city.getCityName().startsWith("-")) {

        convertView = mInflater.inflate(
            R.layout.city_list_item_city_index, null);
        tv = (TextView) convertView
            .findViewById(R.id.city_list_item_city_index);
        tv.setText(city.getCityName().substring(1,
            city.getCityName().length()));

      } else {

        convertView = mInflater.inflate(R.layout.city_list_item_city,
            null);
        tv = (TextView) convertView
            .findViewById(R.id.city_list_item_city);
        tv.setText(city.getCityName());
      }

      return convertView;
    }
  }

  /**
    * 初始化用于显示的数据
    *    
    * @author johnson
    *    
    * */

    
  public void initShowData() {

    list.clear();
    list = Utils.rebuildList(listBasicData);

  }
    
  /**
    * 初始化程序列表索引IndexTextView
    *    
    * @author johnson
    * */
    
    
    
  public void initIndexTextView() {
    mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    listView.setOnScrollListener(this);
    mDialogText = (TextView) mInflater
        .inflate(R.layout.list_position, null);
    mDialogText.setVisibility(View.INVISIBLE);
    mHandler.post(new Runnable() {

      public void run() {
        mReady = true;
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
            LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_STARTING,
            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

        mWindowManager.addView(mDialogText, lp);
      }
    });

  }

}