Android仿IOS三级级联城市选择器
来源:互联网 发布:centos识别不到硬盘 编辑:程序博客网 时间:2024/05/22 09:43
项目用到城市选择,就找了一个大神的代码,自己做了修改后使用的,本程序有两个地方不是很完美:
一、点击popupWindow空白的区域不能关闭popupWindow;
二、选择器那里,不是当前选中的值,不能做到类似IOS里面的折叠,就是类似滚轮的那种立体效果。
望路过的大神们可以加以完善下。
上代码:popup_select_city.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:layout_alignParentBottom="true"> <RelativeLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="44dp" android:paddingLeft="10dp" android:paddingRight="10dp"> <Button android:id="@+id/btn_cancel" android:layout_width="66dp" android:layout_height="match_parent" android:text="取消" android:layout_alignParentLeft="true" android:textSize="18sp" android:textColor="#4a8ff8" android:gravity="center" /> <Button android:id="@+id/btn_confirm" android:layout_width="66dp" android:layout_height="match_parent" android:text="确定" android:layout_alignParentRight="true" android:textSize="18sp" android:textColor="@color/tab_select" android:gravity="center" /> <EditText android:id="@+id/edt_city_select" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/btn_cancel" android:layout_toLeftOf="@id/btn_confirm" android:padding="5dp" android:layout_centerVertical="true" android:hint="请输入省、市、区(县)" android:background="@drawable/border_corner_edit" android:textSize="14sp"/> </RelativeLayout><LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <kankan.wheel.widget.WheelView android:id="@+id/id_province" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" > </kankan.wheel.widget.WheelView> <kankan.wheel.widget.WheelView android:id="@+id/id_city" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" > </kankan.wheel.widget.WheelView> <kankan.wheel.widget.WheelView android:id="@+id/id_district" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" > </kankan.wheel.widget.WheelView> </LinearLayout> </LinearLayout></RelativeLayout>
selectCity.java:
package com.shengping.pao.PopupWindow;import java.io.InputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.json.JSONObject;import kankan.wheel.widget.WheelView;import kankan.wheel.widget.OnWheelChangedListener;import kankan.wheel.widget.adapters.ArrayWheelAdapter;import com.shengping.pao.R;import com.shengping.pao.model.CityModel;import com.shengping.pao.model.DistrictModel;import com.shengping.pao.model.ProvinceModel;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.content.res.AssetManager;import android.graphics.drawable.BitmapDrawable;import android.text.Editable;import android.text.TextWatcher;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.view.ViewGroup;import android.view.WindowManager;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.PopupWindow;public class Select_City implements OnClickListener, OnWheelChangedListener{ private Context context; private View parentView; /** * 取消按钮 */private Button btnCancel; /** * 确定按钮 */private Button btnConfirm;private PopupWindow popupWindow;private WheelView mViewProvince;private WheelView mViewCity;private WheelView mViewDistrict;/** * 所有省 */protected String[] mProvinceDatas;/** * key - 省 value - 市 */protected Map<String, String[]> mCitisDatasMap = new HashMap<String, String[]>();/** * key - 市 values - 区 */protected Map<String, String[]> mDistrictDatasMap = new HashMap<String, String[]>();/** * key - 区 values - 邮编 */protected Map<String, String> mZipcodeDatasMap = new HashMap<String, String>(); /** * 当前省的名称 */protected String mCurrentProviceName;/** * 当前市的名称 */protected String mCurrentCityName;/** * 当前区的名称 */protected String mCurrentDistrictName ="";/** * 当前区的邮政编码 */protected String mCurrentZipCode ="";private View view;private cityselectListener listener;public Select_City(Context activity,View v){ this.context = activity; parentView=v;} @SuppressWarnings("deprecation")@SuppressLint("InflateParams")public Select_City builder(){ // PopView view = LayoutInflater.from(context).inflate( R.layout.popup_select_city, null); initView(view);// android.view.View#getWindowToken() popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); popupWindow.setBackgroundDrawable(new BitmapDrawable()); popupWindow.setOutsideTouchable(true); popupWindow.setFocusable(true); popupWindow.setTouchInterceptor(new OnTouchListener() { @SuppressLint("ClickableViewAccessibility")@Override public boolean onTouch(View v, MotionEvent event) {// System.out.println("touch:"+event.getAction()); if(event.getAction()==MotionEvent.ACTION_OUTSIDE){ popupWindow.dismiss(); return true; } return false; } }); popupWindow.setOnDismissListener(new PopDismissListener()); popupWindow.setAnimationStyle(R.style.PopAnimationDownUp); return this; } public void initView(View contentView){ mViewProvince = (WheelView) contentView.findViewById(R.id.id_province);mViewCity = (WheelView) contentView.findViewById(R.id.id_city);mViewDistrict = (WheelView)contentView. findViewById(R.id.id_district);btnConfirm = (Button)contentView. findViewById(R.id.btn_confirm);btnCancel=(Button)contentView. findViewById(R.id.btn_cancel);// 添加change事件 mViewProvince.addChangingListener(this); // 添加change事件 mViewCity.addChangingListener(this); // 添加change事件 mViewDistrict.addChangingListener(this); // 添加onclick事件 btnConfirm.setOnClickListener(this); btnCancel.setOnClickListener(this); initProvinceDatas();mViewProvince.setViewAdapter(new ArrayWheelAdapter<String>(context, mProvinceDatas));// 设置可见条目数量mViewProvince.setVisibleItems(7);mViewCity.setVisibleItems(7);mViewDistrict.setVisibleItems(7);updateCities();updateAreas();EditText edt_search=(EditText)contentView.findViewById(R.id.edt_city_select);edt_search.addTextChangedListener(new TextWatcher() {@Overridepublic void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}@Overridepublic void beforeTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {// TODO Auto-generated method stub}@Overridepublic void afterTextChanged(Editable arg0) {String str=arg0.toString();int i=0;if(str.equals("")){mViewProvince.setCurrentItem(i);return ;}for(String provence:mProvinceDatas){if(provence.contains(str)){mViewProvince.setCurrentItem(i);return;}i++;}int privenceIndex=0;int cityIndex=0;int districtIndex=0;for(privenceIndex=0;privenceIndex<mProvinceDatas.length;privenceIndex++){String[] citys=mCitisDatasMap.get(mProvinceDatas[privenceIndex]);cityIndex=0; for(String city:citys){ if(city.contains(str)){ mViewProvince.setCurrentItem(privenceIndex); mViewCity.setCurrentItem(cityIndex); return; } cityIndex++; }} privenceIndex=0; cityIndex=0; for(privenceIndex=0;privenceIndex<mProvinceDatas.length;privenceIndex++){String[] citys=mCitisDatasMap.get(mProvinceDatas[privenceIndex]);cityIndex=0; for(String city:citys){ String[] districts=mDistrictDatasMap.get(city); districtIndex=0; for(String district:districts){ if(district.contains(str)){ mViewProvince.setCurrentItem(privenceIndex); mViewCity.setCurrentItem(cityIndex); mViewDistrict.setCurrentItem(districtIndex); if(districtIndex==0){ mCurrentDistrictName = district;mCurrentZipCode = mZipcodeDatasMap.get(mCurrentDistrictName); } return; } districtIndex++; } cityIndex++; }} }}); } /** * 显示 */ @SuppressLint("NewApi")public void show(){ if (null != popupWindow){ setBackgroundAlpha(0.5f); popupWindow.showAtLocation(parentView, Gravity.BOTTOM,0,0); } } /** * 撤销 */ public void dismiss(){ if (null != popupWindow){ popupWindow.dismiss(); } } /** * 设置背景透明度 * @param alpha 背景的Alpha */ private void setBackgroundAlpha(float alpha){ WindowManager.LayoutParams lp = ((Activity)context).getWindow().getAttributes(); lp.alpha = alpha; ((Activity)context).getWindow().setAttributes(lp); } private class PopDismissListener implements PopupWindow.OnDismissListener{ @Override public void onDismiss() { //更改背景透明度 setBackgroundAlpha(1.0f); } }@Overridepublic void onClick(View v) {if(v.getId()==R.id.btn_cancel){dismiss();}else if(v.getId()==R.id.btn_confirm){if(listener!=null){JSONObject json=new JSONObject();try{json.put("mCurrentProviceName", mCurrentProviceName);json.put("mCurrentCityName", mCurrentCityName);json.put("mCurrentDistrictName", mCurrentDistrictName);}catch(Exception e){e.printStackTrace();}listener.selectok(json);dismiss();}}}@Overridepublic void onChanged(WheelView wheel, int oldValue, int newValue) {if (wheel == mViewProvince) {updateCities();} else if (wheel == mViewCity) {updateAreas();} else if (wheel == mViewDistrict) {mCurrentDistrictName = mDistrictDatasMap.get(mCurrentCityName)[newValue];mCurrentZipCode = mZipcodeDatasMap.get(mCurrentDistrictName);}}/** * 解析省市区的XML数据 */ protected void initProvinceDatas(){List<ProvinceModel> provinceList = null; AssetManager asset = context.getAssets(); try { InputStream input = asset.open("province_data.xml"); // 创建一个解析xml的工厂对象SAXParserFactory spf = SAXParserFactory.newInstance();// 解析xmlSAXParser parser = spf.newSAXParser();XmlParserHandler handler = new XmlParserHandler();parser.parse(input, handler);input.close();// 获取解析出来的数据provinceList = handler.getDataList();//*/ 初始化默认选中的省、市、区if (provinceList!= null && !provinceList.isEmpty()) {mCurrentProviceName = provinceList.get(0).getName();List<CityModel> cityList = provinceList.get(0).getCityList();if (cityList!= null && !cityList.isEmpty()) {mCurrentCityName = cityList.get(0).getName();List<DistrictModel> districtList = cityList.get(0).getDistrictList();mCurrentDistrictName = districtList.get(0).getName();mCurrentZipCode = districtList.get(0).getZipcode();}}//*/mProvinceDatas = new String[provinceList.size()]; for (int i=0; i< provinceList.size(); i++) { // 遍历所有省的数据 mProvinceDatas[i] = provinceList.get(i).getName(); List<CityModel> cityList = provinceList.get(i).getCityList(); String[] cityNames = new String[cityList.size()]; for (int j=0; j< cityList.size(); j++) { // 遍历省下面的所有市的数据 cityNames[j] = cityList.get(j).getName(); List<DistrictModel> districtList = cityList.get(j).getDistrictList(); String[] distrinctNameArray = new String[districtList.size()]; DistrictModel[] distrinctArray = new DistrictModel[districtList.size()]; for (int k=0; k<districtList.size(); k++) { // 遍历市下面所有区/县的数据 DistrictModel districtModel = new DistrictModel(districtList.get(k).getName(), districtList.get(k).getZipcode()); // 区/县对于的邮编,保存到mZipcodeDatasMap mZipcodeDatasMap.put(districtList.get(k).getName(), districtList.get(k).getZipcode()); distrinctArray[k] = districtModel; distrinctNameArray[k] = districtModel.getName(); } // 市-区/县的数据,保存到mDistrictDatasMap mDistrictDatasMap.put(cityNames[j], distrinctNameArray); } // 省-市的数据,保存到mCitisDatasMap mCitisDatasMap.put(provinceList.get(i).getName(), cityNames); } } catch (Throwable e) { e.printStackTrace(); } finally { } }/** * 根据当前的省,更新市WheelView的信息 */private void updateCities() {int pCurrent = mViewProvince.getCurrentItem();mCurrentProviceName = mProvinceDatas[pCurrent];String[] cities = mCitisDatasMap.get(mCurrentProviceName);if (cities == null) {cities = new String[] { "" };}mViewCity.setViewAdapter(new ArrayWheelAdapter<String>(context, cities));mViewCity.setCurrentItem(0);updateAreas();}/** * 根据当前的市,更新区WheelView的信息 */private void updateAreas() {int pCurrent = mViewCity.getCurrentItem();mCurrentCityName = mCitisDatasMap.get(mCurrentProviceName)[pCurrent];String[] areas = mDistrictDatasMap.get(mCurrentCityName);if (areas == null) {areas = new String[] { "" };}mViewDistrict.setViewAdapter(new ArrayWheelAdapter<String>(context, areas));mViewDistrict.setCurrentItem(0);}public interface cityselectListener{public void selectok(JSONObject json);}public cityselectListener getListener() {return listener;}public void setListener(cityselectListener listener) {this.listener = listener;}}XmlParserHandler.java
package com.shengping.pao.PopupWindow;import java.util.ArrayList;import java.util.List;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import com.shengping.pao.model.CityModel;import com.shengping.pao.model.DistrictModel;import com.shengping.pao.model.ProvinceModel;public class XmlParserHandler extends DefaultHandler {/** * 存储所有的解析对象 */private List<ProvinceModel> provinceList = new ArrayList<ProvinceModel>(); public XmlParserHandler() {}public List<ProvinceModel> getDataList() {return provinceList;}@Overridepublic void startDocument() throws SAXException {// 当读到第一个开始标签的时候,会触发这个方法}ProvinceModel provinceModel = new ProvinceModel();CityModel cityModel = new CityModel();DistrictModel districtModel = new DistrictModel();@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {// 当遇到开始标记的时候,调用这个方法if (qName.equals("province")) {provinceModel = new ProvinceModel();provinceModel.setName(attributes.getValue(0));provinceModel.setCityList(new ArrayList<CityModel>());} else if (qName.equals("city")) {cityModel = new CityModel();cityModel.setName(attributes.getValue(0));cityModel.setDistrictList(new ArrayList<DistrictModel>());} else if (qName.equals("district")) {districtModel = new DistrictModel();districtModel.setName(attributes.getValue(0));districtModel.setZipcode(attributes.getValue(1));}}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {// 遇到结束标记的时候,会调用这个方法if (qName.equals("district")) {cityModel.getDistrictList().add(districtModel); } else if (qName.equals("city")) { provinceModel.getCityList().add(cityModel); } else if (qName.equals("province")) { provinceList.add(provinceModel); }}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {}}
CityModel.java
package com.shengping.pao.model;import java.util.List;public class CityModel {private String name;private List<DistrictModel> districtList;public CityModel() {super();}public CityModel(String name, List<DistrictModel> districtList) {super();this.name = name;this.districtList = districtList;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<DistrictModel> getDistrictList() {return districtList;}public void setDistrictList(List<DistrictModel> districtList) {this.districtList = districtList;}@Overridepublic String toString() {return "CityModel [name=" + name + ", districtList=" + districtList+ "]";}}
DistrictModel.java
package com.shengping.pao.model;public class DistrictModel {private String name;private String zipcode;public DistrictModel() {super();}public DistrictModel(String name, String zipcode) {super();this.name = name;this.zipcode = zipcode;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getZipcode() {return zipcode;}public void setZipcode(String zipcode) {this.zipcode = zipcode;}@Overridepublic String toString() {return "DistrictModel [name=" + name + ", zipcode=" + zipcode + "]";}}
ProvinceModel.java
package com.shengping.pao.model;import java.util.List;public class ProvinceModel {private String name;private List<CityModel> cityList;public ProvinceModel() {super();}public ProvinceModel(String name, List<CityModel> cityList) {super();this.name = name;this.cityList = cityList;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<CityModel> getCityList() {return cityList;}public void setCityList(List<CityModel> cityList) {this.cityList = cityList;}@Overridepublic String toString() {return "ProvinceModel [name=" + name + ", cityList=" + cityList + "]";}}
使用者只要实现 citiyselectListener接口,即可监听“完成”按钮事件 并获取当前选中的值:
Select_City select_city=new Select_City(getContext(),contentView);
select_city=select_city.builder();
select_city.setListener(listener);
select_city.show();
0 0
- Android仿IOS三级级联城市选择器
- 省市区三级联动城市选择器(仿iOS滚轮实现)
- Android仿iOS实现三级联动选择器
- Android城市三级联动选择器
- Android 仿IOS3D时间选择器城市选择器
- Android 仿IOS3D时间选择器城市选择器
- 高仿iOS 滚轮实现 省市区 城市选择三级联动
- weex 实现仿ios 三级联动地址选择器
- 仿IOS特效(一)——Android 自定义View实现3D滚轮效果的城市联动选择器
- Android 城市三级联动
- Android仿IOS地区弹出框选择器
- Android 仿iOS时间选择器自定义WheelView
- Android仿ios时间日期选择器
- Android中仿IOS圆盘时间选择器
- IOS级联(省份和城市)
- android 城市选择三级联动
- Android:三级城市联动控件
- android选择城市三级联动
- 半全局立体匹配方法调研,以及一些立体匹配方向的思考
- ECSHOP添加购物车加图片飞入效果
- Jenkins Https方式获取Git代码 Failed to connect to repository 错误
- spring环境的搭建及作用和定义<一>
- 2015-11-29 LogCat消失太快&&定时执行任务&&PopuWindow背景模糊
- Android仿IOS三级级联城市选择器
- file not recognized: File format not recognized
- Error:没有这些操作数匹配的"<<"运算符,操作数类型为:std::ostream<<std::string
- 代码整洁之道之命名
- [网络基础]http的重点
- 使用angular.bootstrap完成模块的手动加载
- docker 中 NGINX+PHP+MYSQL+REDIS+Elasticsearch 环境搭建 (linux系统)
- 用JavaScript实现加入书签/收藏本页功能 addBookmark(url, title)
- CombinedDomainXYPlot