在做一些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); } }
运行一下效果:
介于篇幅问题,其他代码大家可以下载源码查看:
喜欢的朋友关注一下我和我的公众号,谢谢!
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-10 14:18:22