项目源码:https://github.com/twjitm/ContactList
在开发过程中兰冕会有选着城市地点等东西,这些都是常用的东西,所以我也就将他封装起来了先来看看效果吧
对于这种效果的,大家可能都能用到,下面我们就来看看怎么实现的吧
其实原理很简单。
先来看看布局代码吧:
mian.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#f0f0f0"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:background="@drawable/title_bar_background" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@drawable/wb_btn_off_normal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="切换城市"
android:textColor="#ffffff"
android:textSize="22sp" />
</RelativeLayout>
<EditText
android:id="@+id/sh"
android:layout_width="fill_parent"
android:layout_height="55dp"
android:layout_below="@id/title"
android:layout_margin="10dip"
android:background="@drawable/cityhot_edittext_bg"
android:drawableLeft="@drawable/wb_search_icon"
android:drawablePadding="5dp"
android:hint="输入城市名或拼音"
android:padding="10dip"
android:textColor="#515151"
android:textSize="16dp" >
</EditText>
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/sh"
android:layout_marginTop="7dp"
android:cacheColorHint="#00000000"
android:divider="#00000000"
android:dividerHeight="0dp"
android:listSelector="@android:color/transparent"
android:scrollbars="none" />
<ListView
android:id="@+id/search_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/sh"
android:layout_marginTop="7dp"
android:cacheColorHint="#00000000"
android:divider="#00000000"
android:dividerHeight="0dp"
android:listSelector="@android:color/transparent"
android:scrollbars="none"
android:visibility="gone" />
<TextView
android:id="@+id/tv_noresult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/sh"
android:gravity="center"
android:padding="10dp"
android:text="抱歉,暂时没有找到相关城市"
android:textColor="#000000"
android:textSize="16sp"
android:visibility="gone" />
<com.droid.MyLetterListView
android:id="@+id/MyLetterListView01"
android:layout_width="25dip"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_below="@id/sh"
android:layout_marginRight="2dp"
android:layout_marginTop="7dp" />
</RelativeLayout>
fist_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/locate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:id="@+id/locateHint"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dip"
android:gravity="center_vertical"
android:text="当前定位城市"
android:textColor="#000000"
android:textSize="16sp" />
<TextView
android:id="@+id/lng_city"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:layout_marginRight="40dip"
android:background="@drawable/text_selector"
android:clickable="true"
android:focusable="false"
android:gravity="center"
android:text="保定"
android:textColor="#ffffff"
android:textSize="16sp" />
<ProgressBar
android:id="@+id/pbLocate"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginBottom="5dp"
android:layout_marginRight="64dip"
android:layout_marginTop="13dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="25dp"
android:layout_marginTop="50dp"
android:background="#E2E2E2" />
</RelativeLayout>
list.item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/alpha"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="12dp"
android:background="#F7F6F4"
android:gravity="center"
android:textColor="#8E8D8B"
android:textSize="30sp"
android:visibility="gone" />
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dip"
android:textColor="#FF767676"
android:textSize="16dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="25dp"
android:background="#E2E2E2" />
</LinearLayout>
recent_city.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/recentHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="7dp"
android:text="最近访问城市"
android:textColor="#000000"
android:textSize="16sp" />
<com.droid.MyGridView
android:id="@+id/recent_city"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="30dp"
android:layout_marginTop="15dp"
android:horizontalSpacing="20dp"
android:listSelector="@android:color/transparent"
android:numColumns="3"
android:verticalSpacing="10dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="25dp"
android:layout_marginTop="15dp"
android:background="#E2E2E2" />
</LinearLayout>
total_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/locate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:id="@+id/locateHint"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="10dip"
android:gravity="center_vertical"
android:text="全部城市"
android:textColor="#000000"
android:textSize="16sp" />
</RelativeLayout>
上面都是一些布局文件,其实最重要的是如何实现list索引的,自定义一个listview,关于自定义控键,小伙伴们应该很熟悉了,要不熟悉的自己补脑吧!
来看看自定义listview吧,
package com.droid;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class MyLetterListView extends View {
OnTouchingLetterChangedListener onTouchingLetterChangedListener;
String[] b = {"定位", "最近", "热门", "全部", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
"Y", "Z" };
int choose = -1;
Paint paint = new Paint();
boolean showBkg = false;
public MyLetterListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyLetterListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLetterListView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (showBkg) {
canvas.drawColor(Color.parseColor("#40000000"));
}
int height = getHeight();
int width = getWidth();
int singleHeight = height / b.length;
for (int i = 0; i < b.length; i++) {
paint.setColor(Color.parseColor("#8c8c8c"));
paint.setTextSize(26);
// paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
/*if (i == choose) {
paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);
}*/
float xPos = width / 2 - paint.measureText(b[i]) / 2;
float yPos = singleHeight * i + singleHeight;
canvas.drawText(b[i], xPos, yPos, paint);
paint.reset();
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
final float y = event.getY();
final int oldChoose = choose;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int c = (int) (y / getHeight() * b.length);
switch (action) {
case MotionEvent.ACTION_DOWN:
showBkg = true;
if (oldChoose != c && listener != null) {
if (c >= 0 && c < b.length) {
listener.onTouchingLetterChanged(b[c]);
choose = c;
invalidate();
}
}
break;
case MotionEvent.ACTION_MOVE:
if (oldChoose != c && listener != null) {
if (c >= 0 && c < b.length) {
listener.onTouchingLetterChanged(b[c]);
choose = c;
invalidate();
}
}
break;
case MotionEvent.ACTION_UP:
showBkg = false;
choose = -1;
invalidate();
break;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
}
下面就是在activity中测试了,
package com.droid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.droid.MyLetterListView.OnTouchingLetterChangedListener;
public class Activity01 extends Activity implements OnScrollListener {
private BaseAdapter adapter;
private ResultListAdapter resultListAdapter;
private ListView personList;
private ListView resultList;
private TextView overlay; // 对话框首字母textview
private MyLetterListView letterListView; // A-Z listview
private HashMap<String, Integer> alphaIndexer;// 存放存在的汉语拼音首字母和与之对应的列表位置
private String[] sections;// 存放存在的汉语拼音首字母
private Handler handler;
private OverlayThread overlayThread; // 显示首字母对话框
private ArrayList<City> allCity_lists; // 所有城市列表
private ArrayList<City> city_lists;// 城市列表
private ArrayList<City> city_hot;
private ArrayList<City> city_result;
private ArrayList<String> city_history;
private EditText sh;
private TextView tv_noresult;
private LocationClient mLocationClient;
private MyLocationListener mMyLocationListener;
private String currentCity; // 用于保存定位到的城市
private int locateProcess = 1; // 记录当前定位的状态 正在定位-定位成功-定位失败
private boolean isNeedFresh;
private DatabaseHelper helper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
personList = (ListView) findViewById(R.id.list_view);
allCity_lists = new ArrayList<City>();
city_hot = new ArrayList<City>();
city_result = new ArrayList<City>();
city_history = new ArrayList<String>();
resultList = (ListView) findViewById(R.id.search_result);
sh = (EditText) findViewById(R.id.sh);
tv_noresult = (TextView) findViewById(R.id.tv_noresult);
helper = new DatabaseHelper(this);
sh.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (s.toString() == null || "".equals(s.toString())) {
letterListView.setVisibility(View.VISIBLE);
personList.setVisibility(View.VISIBLE);
resultList.setVisibility(View.GONE);
tv_noresult.setVisibility(View.GONE);
} else {
city_result.clear();
letterListView.setVisibility(View.GONE);
personList.setVisibility(View.GONE);
getResultCityList(s.toString());
if (city_result.size() <= 0) {
tv_noresult.setVisibility(View.VISIBLE);
resultList.setVisibility(View.GONE);
} else {
tv_noresult.setVisibility(View.GONE);
resultList.setVisibility(View.VISIBLE);
resultListAdapter.notifyDataSetChanged();
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
letterListView = (MyLetterListView) findViewById(R.id.MyLetterListView01);
letterListView
.setOnTouchingLetterChangedListener(new LetterListViewListener());
alphaIndexer = new HashMap<String, Integer>();
handler = new Handler();
overlayThread = new OverlayThread();
isNeedFresh = true;
personList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (position >= 4) {
Toast.makeText(getApplicationContext(),
allCity_lists.get(position).getName(),
Toast.LENGTH_SHORT).show();
}
}
});
locateProcess = 1;
personList.setAdapter(adapter);
personList.setOnScrollListener(this);
resultListAdapter = new ResultListAdapter(this, city_result);
resultList.setAdapter(resultListAdapter);
resultList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
city_result.get(position).getName(), Toast.LENGTH_SHORT)
.show();
}
});
initOverlay();
cityInit();
hotCityInit();
hisCityInit();
setAdapter(allCity_lists, city_hot, city_history);
mLocationClient = new LocationClient(this.getApplicationContext());
mMyLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(mMyLocationListener);
InitLocation();
mLocationClient.start();
}
public void InsertCity(String name) {
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from recentcity where name = '"
+ name + "'", null);
if (cursor.getCount() > 0) { //
db.delete("recentcity", "name = ?", new String[] { name });
}
db.execSQL("insert into recentcity(name, date) values('" + name + "', "
+ System.currentTimeMillis() + ")");
db.close();
}
private void InitLocation() {
// 设置定位参数
LocationClientOption option = new LocationClientOption();
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(10000); // 10分钟扫描1次
// 需要地址信息,设置为其他任何值(string类型,且不能为null)时,都表示无地址信息。
option.setAddrType("all");
// 设置是否返回POI的电话和地址等详细信息。默认值为false,即不返回POI的电话和地址信息。
option.setPoiExtraInfo(true);
// 设置产品线名称。强烈建议您使用自定义的产品线名称,方便我们以后为您提供更高效准确的定位服务。
option.setProdName("通过GPS定位我当前的位置");
// 禁用启用缓存定位数据
option.disableCache(true);
// 设置最多可返回的POI个数,默认值为3。由于POI查询比较耗费流量,设置最多返回的POI个数,以便节省流量。
option.setPoiNumber(3);
// 设置定位方式的优先级。
// 当gps可用,而且获取了定位结果时,不再发起网络请求,直接返回给用户坐标。这个选项适合希望得到准确坐标位置的用户。如果gps不可用,再发起网络请求,进行定位。
option.setPriority(LocationClientOption.GpsFirst);
mLocationClient.setLocOption(option);
}
private void cityInit() {
City city = new City("定位", "0"); // 当前定位城市
allCity_lists.add(city);
city = new City("最近", "1"); // 最近访问的城市
allCity_lists.add(city);
city = new City("热门", "2"); // 热门城市
allCity_lists.add(city);
city = new City("全部", "3"); // 全部城市
allCity_lists.add(city);
city_lists = getCityList();
allCity_lists.addAll(city_lists);
}
/**
* 热门城市
*/
public void hotCityInit() {
City city = new City("上海", "2");
city_hot.add(city);
city = new City("北京", "2");
city_hot.add(city);
city = new City("广州", "2");
city_hot.add(city);
city = new City("深圳", "2");
city_hot.add(city);
city = new City("武汉", "2");
city_hot.add(city);
city = new City("天津", "2");
city_hot.add(city);
city = new City("西安", "2");
city_hot.add(city);
city = new City("南京", "2");
city_hot.add(city);
city = new City("杭州", "2");
city_hot.add(city);
city = new City("成都", "2");
city_hot.add(city);
city = new City("重庆", "2");
city_hot.add(city);
}
private void hisCityInit() {
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.rawQuery(
"select * from recentcity order by date desc limit 0, 3", null);
while (cursor.moveToNext()) {
city_history.add(cursor.getString(1));
}
cursor.close();
db.close();
}
@SuppressWarnings("unchecked")
private ArrayList<City> getCityList() {
DBHelper dbHelper = new DBHelper(this);
ArrayList<City> list = new ArrayList<City>();
try {
dbHelper.createDataBase();
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("select * from city", null);
City city;
while (cursor.moveToNext()) {
city = new City(cursor.getString(1), cursor.getString(2));
list.add(city);
}
cursor.close();
db.close();
} catch (IOException e) {
e.printStackTrace();
}
Collections.sort(list, comparator);
return list;
}
@SuppressWarnings("unchecked")
private void getResultCityList(String keyword) {
DBHelper dbHelper = new DBHelper(this);
try {
dbHelper.createDataBase();
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery(
"select * from city where name like \"%" + keyword
+ "%\" or pinyin like \"%" + keyword + "%\"", null);
City city;
Log.e("info", "length = " + cursor.getCount());
while (cursor.moveToNext()) {
city = new City(cursor.getString(1), cursor.getString(2));
city_result.add(city);
}
cursor.close();
db.close();
} catch (IOException e) {
e.printStackTrace();
}
Collections.sort(city_result, comparator);
}
/**
* a-z排序
*/
@SuppressWarnings("rawtypes")
Comparator comparator = new Comparator<City>() {
@Override
public int compare(City lhs, City rhs) {
String a = lhs.getPinyi().substring(0, 1);
String b = rhs.getPinyi().substring(0, 1);
int flag = a.compareTo(b);
if (flag == 0) {
return a.compareTo(b);
} else {
return flag;
}
}
};
private void setAdapter(List<City> list, List<City> hotList,
List<String> hisCity) {
adapter = new ListAdapter(this, list, hotList, hisCity);
personList.setAdapter(adapter);
}
/**
* 实现实位回调监听
*/
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation arg0) {
Log.e("info", "city = " + arg0.getCity());
if (!isNeedFresh) {
return;
}
isNeedFresh = false;
if (arg0.getCity() == null) {
locateProcess = 3; // 定位失败
personList.setAdapter(adapter);
adapter.notifyDataSetChanged();
return;
}
currentCity = arg0.getCity().substring(0,
arg0.getCity().length() - 1);
locateProcess = 2; // 定位成功
personList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
@Override
public void onReceivePoi(BDLocation arg0) {
}
}
private class ResultListAdapter extends BaseAdapter {
private LayoutInflater inflater;
private ArrayList<City> results = new ArrayList<City>();
public ResultListAdapter(Context context, ArrayList<City> results) {
inflater = LayoutInflater.from(context);
this.results = results;
}
@Override
public int getCount() {
return results.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item, null);
viewHolder = new ViewHolder();
viewHolder.name = (TextView) convertView
.findViewById(R.id.name);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.name.setText(results.get(position).getName());
return convertView;
}
class ViewHolder {
TextView name;
}
}
public class ListAdapter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private List<City> list;
private List<City> hotList;
private List<String> hisCity;
final int VIEW_TYPE = 5;
public ListAdapter(Context context, List<City> list,
List<City> hotList, List<String> hisCity) {
this.inflater = LayoutInflater.from(context);
this.list = list;
this.context = context;
this.hotList = hotList;
this.hisCity = hisCity;
alphaIndexer = new HashMap<String, Integer>();
sections = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
// 当前汉语拼音首字母
String currentStr = getAlpha(list.get(i).getPinyi());
// 上一个汉语拼音首字母,如果不存在为" "
String previewStr = (i - 1) >= 0 ? getAlpha(list.get(i - 1)
.getPinyi()) : " ";
if (!previewStr.equals(currentStr)) {
String name = getAlpha(list.get(i).getPinyi());
alphaIndexer.put(name, i);
sections[i] = name;
}
}
}
@Override
public int getViewTypeCount() {
return VIEW_TYPE;
}
@Override
public int getItemViewType(int position) {
return position < 4 ? position : 4;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
ViewHolder holder;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final TextView city;
int viewType = getItemViewType(position);
if (viewType == 0) { // 定位
convertView = inflater.inflate(R.layout.frist_list_item, null);
TextView locateHint = (TextView) convertView
.findViewById(R.id.locateHint);
city = (TextView) convertView.findViewById(R.id.lng_city);
city.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (locateProcess == 2) {
Toast.makeText(getApplicationContext(),
city.getText().toString(),
Toast.LENGTH_SHORT).show();
} else if (locateProcess == 3) {
locateProcess = 1;
personList.setAdapter(adapter);
adapter.notifyDataSetChanged();
mLocationClient.stop();
isNeedFresh = true;
InitLocation();
currentCity = "";
mLocationClient.start();
}
}
});
ProgressBar pbLocate = (ProgressBar) convertView
.findViewById(R.id.pbLocate);
if (locateProcess == 1) { // 正在定位
locateHint.setText("正在定位");
city.setVisibility(View.GONE);
pbLocate.setVisibility(View.VISIBLE);
} else if (locateProcess == 2) { // 定位成功
locateHint.setText("当前定位城市");
city.setVisibility(View.VISIBLE);
city.setText(currentCity);
mLocationClient.stop();
pbLocate.setVisibility(View.GONE);
} else if (locateProcess == 3) {
locateHint.setText("未定位到城市,请选择");
city.setVisibility(View.VISIBLE);
city.setText("重新选择");
pbLocate.setVisibility(View.GONE);
}
} else if (viewType == 1) { // 最近访问城市
convertView = inflater.inflate(R.layout.recent_city, null);
GridView rencentCity = (GridView) convertView
.findViewById(R.id.recent_city);
rencentCity
.setAdapter(new HitCityAdapter(context, this.hisCity));
rencentCity.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
city_history.get(position), Toast.LENGTH_SHORT)
.show();
}
});
TextView recentHint = (TextView) convertView
.findViewById(R.id.recentHint);
recentHint.setText("最近访问的城市");
} else if (viewType == 2) {
convertView = inflater.inflate(R.layout.recent_city, null);
GridView hotCity = (GridView) convertView
.findViewById(R.id.recent_city);
hotCity.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
city_hot.get(position).getName(),
Toast.LENGTH_SHORT).show();
}
});
hotCity.setAdapter(new HotCityAdapter(context, this.hotList));
TextView hotHint = (TextView) convertView
.findViewById(R.id.recentHint);
hotHint.setText("热门城市");
} else if (viewType == 3) {
convertView = inflater.inflate(R.layout.total_item, null);
} else {
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.alpha = (TextView) convertView
.findViewById(R.id.alpha);
holder.name = (TextView) convertView
.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (position >= 1) {
holder.name.setText(list.get(position).getName());
String currentStr = getAlpha(list.get(position).getPinyi());
String previewStr = (position - 1) >= 0 ? getAlpha(list
.get(position - 1).getPinyi()) : " ";
if (!previewStr.equals(currentStr)) {
holder.alpha.setVisibility(View.VISIBLE);
holder.alpha.setText(currentStr);
} else {
holder.alpha.setVisibility(View.GONE);
}
}
}
return convertView;
}
private class ViewHolder {
TextView alpha; // 首字母标题
TextView name; // 城市名字
}
}
@Override
protected void onStop() {
mLocationClient.stop();
super.onStop();
}
class HotCityAdapter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private List<City> hotCitys;
public HotCityAdapter(Context context, List<City> hotCitys) {
this.context = context;
inflater = LayoutInflater.from(this.context);
this.hotCitys = hotCitys;
}
@Override
public int getCount() {
return hotCitys.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.item_city, null);
TextView city = (TextView) convertView.findViewById(R.id.city);
city.setText(hotCitys.get(position).getName());
return convertView;
}
}
class HitCityAdapter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private List<String> hotCitys;
public HitCityAdapter(Context context, List<String> hotCitys) {
this.context = context;
inflater = LayoutInflater.from(this.context);
this.hotCitys = hotCitys;
}
@Override
public int getCount() {
return hotCitys.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.item_city, null);
TextView city = (TextView) convertView.findViewById(R.id.city);
city.setText(hotCitys.get(position));
return convertView;
}
}
private boolean mReady;
// 初始化汉语拼音首字母弹出提示框
private void initOverlay() {
mReady = true;
LayoutInflater inflater = LayoutInflater.from(this);
overlay = (TextView) inflater.inflate(R.layout.overlay, null);
overlay.setVisibility(View.INVISIBLE);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
WindowManager windowManager = (WindowManager) this
.getSystemService(Context.WINDOW_SERVICE);
windowManager.addView(overlay, lp);
}
private boolean isScroll = false;
private class LetterListViewListener implements
OnTouchingLetterChangedListener {
@Override
public void onTouchingLetterChanged(final String s) {
isScroll = false;
if (alphaIndexer.get(s) != null) {
int position = alphaIndexer.get(s);
personList.setSelection(position);
overlay.setText(s);
overlay.setVisibility(View.VISIBLE);
handler.removeCallbacks(overlayThread);
// 延迟一秒后执行,让overlay为不可见
handler.postDelayed(overlayThread, 1000);
}
}
}
// 设置overlay不可见
private class OverlayThread implements Runnable {
@Override
public void run() {
overlay.setVisibility(View.GONE);
}
}
// 获得汉语拼音首字母
private String getAlpha(String str) {
if (str == null) {
return "#";
}
if (str.trim().length() == 0) {
return "#";
}
char c = str.trim().substring(0, 1).charAt(0);
// 正则表达式,判断首字母是否是英文字母
Pattern pattern = Pattern.compile("^[A-Za-z]+$");
if (pattern.matcher(c + "").matches()) {
return (c + "").toUpperCase();
} else if (str.equals("0")) {
return "定位";
} else if (str.equals("1")) {
return "最近";
} else if (str.equals("2")) {
return "热门";
} else if (str.equals("3")) {
return "全部";
} else {
return "#";
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_TOUCH_SCROLL
|| scrollState == SCROLL_STATE_FLING) {
isScroll = true;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (!isScroll) {
return;
}
if (mReady) {
String text;
String name = allCity_lists.get(firstVisibleItem).getName();
String pinyin = allCity_lists.get(firstVisibleItem).getPinyi();
if (firstVisibleItem < 4) {
text = name;
} else {
text = PingYinUtil.converterToFirstSpell(pinyin)
.substring(0, 1).toUpperCase();
}
overlay.setText(text);
overlay.setVisibility(View.VISIBLE);
handler.removeCallbacks(overlayThread);
// 延迟一秒后执行,让overlay为不可见
handler.postDelayed(overlayThread, 1000);
}
}
}
还有一部分代码比较多,就不一一贴上了,要源码的小伙伴添加关注然后留下邮箱,