在做一些APP的时候可能会用到城市选择模块的功能,本实例可以提供位置自定定位和手动选择的功能,非常好用,大家可以修改后加入自己的项目中。
首先看一下效果:
1.进入有的手机可能会提示权限要求,这时我们选择允许。
2.选择允许后进入:
这个位置可以看到我们的城市已经通过GPS获取到了
点击这个控件,城市获取完成了:
下面我们看一下关键代码如何实现这个功能效果。
1.MainActivity.java:
- package com.winxiang.locationselect;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- private TextView city_name;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- city_name = (TextView) findViewById(R.id.city_name);
- }
- public void goSelcet(View v){
- startActivityForResult(new Intent(MainActivity.this,ActivitySelectCity.class), 99);
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- // TODO Auto-generated method stub
- try{
- switch (resultCode) {
- case 99:
- city_name.setText(data.getStringExtra("lngCityName"));
- break;
- default:
- break;
- }
- }catch (Exception e) {
- e.printStackTrace();
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
2.ActivitySelectCity.java:
- package com.winxiang.locationselect;
- 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 org.json.JSONArray;
- import org.json.JSONObject;
- import com.baidu.location.BDLocation;
- import com.baidu.location.BDLocationListener;
- import com.baidu.location.LocationClient;
- import com.baidu.location.LocationClientOption;
- import android.app.Activity;
- import android.app.ProgressDialog;
- import android.content.Context;
- import android.content.Intent;
- 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.View.OnClickListener;
- import android.view.ViewGroup;
- import android.view.ViewGroup.LayoutParams;
- import android.view.WindowManager;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.BaseAdapter;
- import android.widget.EditText;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.TextView;
- import com.winxiang.locationselect.MyLetterListView.OnTouchingLetterChangedListener;
- public class ActivitySelectCity extends Activity{
- private ListAdapter adapter;
- private ListView personList;
- private ImageView imgback;
- 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> ShowCity_lists; // 需要显示的城市列表-随搜索而改变
- private ArrayList<City> city_lists;// 城市列表
- private String lngCityName ="";//存放返回的城市名
- private JSONArray chineseCities ;
- private LocationClient locationClient = null;
- private EditText sh;
- private TextView lng_city;
- private LinearLayout lng_city_lay;
- private ProgressDialog progress;
- private static final int SHOWDIALOG = 2;
- private static final int DISMISSDIALOG = 3;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_selectcity);
- personList = (ListView) findViewById(R.id.list_view);
- allCity_lists = new ArrayList<City>();
- letterListView = (MyLetterListView) findViewById(R.id.MyLetterListView01);
- lng_city_lay = (LinearLayout) findViewById(R.id.lng_city_lay);
- sh = (EditText) findViewById(R.id.sh);
- lng_city = (TextView) findViewById(R.id.lng_city);
- imgback = (ImageView) findViewById(R.id.imgback);
- letterListView.setOnTouchingLetterChangedListener(new LetterListViewListener());
- alphaIndexer = new HashMap<String, Integer>();
- handler = new Handler();
- overlayThread = new OverlayThread();
- personList.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
- long arg3) {
- Intent intent = new Intent();
- intent.putExtra("lngCityName", ShowCity_lists.get(arg2).name);
- setResult(99,intent);
- finish();
- }
- });
- lng_city_lay.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.putExtra("lngCityName",lngCityName);
- setResult(99,intent);
- finish();
- }
- });
- imgback.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
- initGps();
- initOverlay();
- handler2.sendEmptyMessage(SHOWDIALOG);
- Thread thread = new Thread(){
- @Override
- public void run() {
- hotCityInit();
- handler2.sendEmptyMessage(DISMISSDIALOG);
- super.run();
- }
- };
- thread.start();
- }
- /**
- * 热门城市
- */
- public void hotCityInit() {
- City city;
- city = new City("上海", "");
- allCity_lists.add(city);
- city = new City("北京", "");
- allCity_lists.add(city);
- city = new City("广州", "");
- allCity_lists.add(city);
- city = new City("深圳", "");
- allCity_lists.add(city);
- city = new City("武汉", "");
- allCity_lists.add(city);
- city = new City("天津", "");
- allCity_lists.add(city);
- city = new City("西安", "");
- allCity_lists.add(city);
- city = new City("南京", "");
- allCity_lists.add(city);
- city = new City("杭州", "");
- allCity_lists.add(city);
- city = new City("成都", "");
- allCity_lists.add(city);
- city = new City("重庆", "");
- allCity_lists.add(city);
- city_lists = getCityList();
- allCity_lists.addAll(city_lists);
- ShowCity_lists=allCity_lists;
- }
- /**
- *
- * 通过json数据获取城市列表
- * @author yayun
- * @since 2015年9月18日
- *@return
- */
- private ArrayList<City> getCityList() {
- ArrayList<City> list = new ArrayList<City>();
- try {
- chineseCities = new JSONArray(getResources().getString(R.string.citys));
- for(int i=0;i<chineseCities.length();i++){
- JSONObject jsonObject = chineseCities.getJSONObject(i);
- City city = new City(jsonObject.getString("name"), jsonObject.getString("pinyin"));
- list.add(city);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- Collections.sort(list, comparator);
- return list;
- }
- /**
- * a-z排序
- */
- 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;
- }
- }
- };
- /**
- * ListView的adapter
- * @author yayun
- * @since 2015年9月18日
- *
- */
- public class ListAdapter extends BaseAdapter {
- private LayoutInflater inflater;
- final int VIEW_TYPE = 3;
- public ListAdapter(Context context) {
- this.inflater = LayoutInflater.from(context);
- alphaIndexer = new HashMap<String, Integer>();
- sections = new String[ShowCity_lists.size()];
- for (int i = 0; i < ShowCity_lists.size(); i++) {
- // 当前汉语拼音首字母
- String currentStr = getAlpha(ShowCity_lists.get(i).getPinyi());
- // 上一个汉语拼音首字母,如果不存在为“ ”
- String previewStr = (i - 1) >= 0 ? getAlpha(ShowCity_lists.get(i - 1)
- .getPinyi()) : " ";
- if (!previewStr.equals(currentStr)) {
- String name = getAlpha(ShowCity_lists.get(i).getPinyi());
- alphaIndexer.put(name, i);
- sections[i] = name;
- }
- }
- }
- @Override
- public int getCount() {
- return ShowCity_lists.size();
- }
- @Override
- public Object getItem(int position) {
- return ShowCity_lists.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- @Override
- public int getItemViewType(int position) {
- // TODO Auto-generated method stub
- int type = 2;
- if (position == 0&&sh.getText().length()==0) {//不是在搜索状态下
- type = 0;
- }
- return type;
- }
- @Override
- public int getViewTypeCount() {// 这里需要返回需要集中布局类型,总大小为类型的种数的下标
- return VIEW_TYPE;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
- int viewType = getItemViewType(position);
- 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 (sh.getText().length()==0) {//搜所状态
- // holder.name.setText(list.get(position).getName());
- // holder.alpha.setVisibility(View.GONE);
- // }else if(position>0){
- //显示拼音和热门城市,一次检查本次拼音和上一个字的拼音,如果一样则不显示,如果不一样则显示
- holder.name.setText(ShowCity_lists.get(position).getName());
- String currentStr = getAlpha(ShowCity_lists.get(position).getPinyi());//本次拼音
- String previewStr = (position-1) >= 0 ? getAlpha(ShowCity_lists.get(position-1).getPinyi()) : " ";//上一个拼音
- if (!previewStr.equals(currentStr)) {//不一样则显示
- holder.alpha.setVisibility(View.VISIBLE);
- if (currentStr.equals("#")) {
- currentStr = "热门城市";
- }
- holder.alpha.setText(currentStr);
- } else {
- holder.alpha.setVisibility(View.GONE);
- }
- // }
- return convertView;
- }
- private class ViewHolder {
- TextView alpha; // 首字母标题
- TextView name; // 城市名字
- }
- }
- // 初始化汉语拼音首字母弹出提示框
- private void initOverlay() {
- 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 class LetterListViewListener implements
- OnTouchingLetterChangedListener {
- @Override
- public void onTouchingLetterChanged(final String s) {
- if (alphaIndexer.get(s) != null) {
- int position = alphaIndexer.get(s);
- personList.setSelection(position);
- overlay.setText(sections[position]);
- overlay.setVisibility(View.VISIBLE);
- handler.removeCallbacks(overlayThread);
- // 延迟一秒后执行,让overlay为不可见
- handler.postDelayed(overlayThread, 1500);
- }
- }
- }
- // 设置overlay不可见
- private class OverlayThread implements Runnable {
- @Override
- public void run() {
- overlay.setVisibility(View.GONE);
- }
- }
- // 获得汉语拼音首字母
- private String getAlpha(String str) {
- if (str.equals("-")) {
- return "&";
- }
- 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 {
- return "#";
- }
- }
- /**
- *
- * 初始化GPS
- * @author yayun
- * @since 2015年9月18日
- */
- private void initGps() {
- try{
- MyLocationListenner myListener = new MyLocationListenner();
- locationClient = new LocationClient(ActivitySelectCity.this);
- locationClient.registerLocationListener(myListener);
- LocationClientOption option = new LocationClientOption();
- option.setOpenGps(true);
- option.setAddrType("all");
- option.setCoorType("bd09ll");
- option.setScanSpan(5000);
- option.disableCache(true);
- option.setPoiNumber(5);
- option.setPoiDistance(1000);
- option.setPoiExtraInfo(true);
- option.setPriority(LocationClientOption.GpsFirst);
- locationClient.setLocOption(option);
- locationClient.start();
- }catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 销毁
- */
- @Override
- public void onDestroy() {
- super.onDestroy();
- locationClient.stop();
- }
- /**
- * 通过位置SDK获取现在所在城市
- * @author yayun
- * @since 2015年9月18日
- *
- */
- private class MyLocationListenner implements BDLocationListener {
- @Override
- public void onReceiveLocation(BDLocation location) {
- if (location == null)
- return;
- StringBuffer sb = new StringBuffer(256);
- if (location.getLocType() == BDLocation.TypeGpsLocation) {
- sb.append(location.getCity());
- } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
- sb.append(location.getCity());
- }
- if (sb.toString() != null && sb.toString().length() > 0) {
- lngCityName=sb.toString();
- lng_city.setText(lngCityName);
- }
- }
- public void onReceivePoi(BDLocation poiLocation) {
- }
- }
- Handler handler2 = new Handler(){
- public void handleMessage(android.os.Message msg) {
- switch (msg.what) {
- case SHOWDIALOG:
- progress = AppUtil.showProgress(ActivitySelectCity.this, "正在加载数据,请稍候...");
- break;
- case DISMISSDIALOG:
- if (progress != null)
- {
- progress.dismiss();
- }
- adapter = new ListAdapter(ActivitySelectCity.this);
- personList.setAdapter(adapter);
- // personList.setAdapter(adapter);
- sh.addTextChangedListener(new TextWatcher() {
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
- @Override
- public void afterTextChanged(Editable s) {
- //搜索符合用户输入的城市名
- if(s.length()>0){
- ArrayList<City> changecity = new ArrayList<City>();
- for(int i=0;i<city_lists.size();i++){
- if(city_lists.get(i).name.indexOf(sh.getText().toString())!=-1){
- changecity.add(city_lists.get(i));
- }
- }
- ShowCity_lists = changecity;
- }else{
- ShowCity_lists = allCity_lists;
- }
- adapter.notifyDataSetChanged();
- }
- });
- break;
- default:
- break;
- }
- };
- };
- }
3.自定义控件(快速索引):
- package com.winxiang.locationselect;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Typeface;
- import android.text.style.TypefaceSpan;
- 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("#10000000"));
- }
- int height = getHeight();
- int width = getWidth();
- int singleHeight = height / b.length;
- for (int i = 0; i < b.length; i++) {
- paint.setColor(Color.parseColor("#515151"));
- 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);
- }
- }
介于篇幅问题,其他代码大家可以下载源码查看: