短短的国庆8天假期一眨眼就过去了,下次长假只有等到过年了,本宝宝不开心。既然已经开始工作了,就要好好多学习点新知识,来提高自己的代码能力,今天带大家去实现简易的选择城市界面,并且可以根据城市首字母或者拼音搜索。先来看下我的效果图:
在写代码之前先准备好一个城市列表的json文件以及去百度或者高德申请定位功能,Demo在文章最后。(Demo里没有写定位功能,需要自己实现哦~)
实现方法也比较简单,我就简单的给大家说一下,整个城市列表是用的一个ListView,方便我们后面监听它的滚动状态,右边的快速定位栏是自定义View,代码比较简单,我就直接放代码了。不知道大家发现没有,有些字母开头的城市是没有的,比如 I,O,U,V等等,为了节约空间我就把那几个字母去掉了,有的软件是把26个字母全部保留了。
(其实都不影响,看你个人吧,我反正是有强迫症的。)注意,在自定义View的时候三种构造方法都要写上,千万不要偷懒!!!哎,都是泪 o(╥﹏╥)o
public class LetterListView extends View {OnTouchingLetterChangedListener onTouchingLetterChangedListener;public static String[] b = {"定位", "热门", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K","L", "M", "N", "P", "Q", "R", "S", "T", "W", "X", "Y", "Z"};int choose = -1;Paint paint = new Paint();boolean showBkg = false;private Context mContext;public LetterListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);}public LetterListView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public LetterListView(Context context) {super(context);init(context);}private void init(Context context){this.mContext = context;paint.setColor(Color.parseColor("#50B3DA"));paint.setTextSize(DisplayUtil.sp2px(mContext, 12));paint.setAntiAlias(true);}@Overrideprotected 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
使用的时候设置好宽度和高度:
接下来就是关键的地方了,咳咳~
一、 既然左边用到了ListView,那就少不了适配器和城市模型。
①、城市模型:其中拼音和首字母是方便用户搜索的时候进行筛选,CityCode你们可以不用去管,我主要是用来请求数据。
public class CityEntity {private String name;private String key;private String pinyin; //全拼private String first; //首字母private String cityCode;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}public String getPinyin() {return pinyin;}public void setPinyin(String pinyin) {this.pinyin = pinyin;}public String getFirst() {return first;}public void setFirst(String first) {this.first = first;}public String getCityCode() {return cityCode;}public void setCityCode(String cityCode) {this.cityCode = cityCode;}
}
②、全部城市列表的适配器:我这里将全部城市列表分成了三种类型,第一种就是当前定位城市的布局,第二种就是热门城市的布局,(当然了,热门城市你们可以从后台获取,我图方便就写死在本地了),第三种就是全部城市的布局了
/*** 总城市适配器*/private class CityListAdapter extends BaseAdapter {private Context context;private List
1)、当前定位城市布局:定位失败的话显示出来,并且提示用户去开启GPS
2)、热门城市布局:记住,这里直接使用GridView的话只会显示一行数据,需要继承GridView并重写OnMeasure方法,网上有很多案例,就不放代码了。
3)、全部城市的单行布局:每绘制一条数据判断前一个数据的Key是否与现在的相同,true则不显示 city_key_tv,保证同一个Key的城市只有一个显示。
③、热门城市列表适配器:比较简单,不过多说明。
/*** 热门城市适配器*/private class HotCityListAdapter extends BaseAdapter {private List
二、初始化首字母提示框,并且设置ListVIew的滚动监听以及自定义View的Touch事件
/*** 初始化汉语拼音首字母弹出提示框*/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(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.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 implementsLetterListView.OnTouchingLetterChangedListener {@Overridepublic void onTouchingLetterChanged(final String s) {isScroll = false;if (alphaIndexer.get(s) != null) {int position = alphaIndexer.get(s);totalCityLv.setSelection(position);overlay.setText(s);overlay.setVisibility(View.VISIBLE);handler.removeCallbacks(overlayThread);// 延迟让overlay为不可见handler.postDelayed(overlayThread, 700);}}}/*** 设置overlay不可见*/private class OverlayThread implements Runnable {@Overridepublic void run() {overlay.setVisibility(View.GONE);}}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {if (scrollState == SCROLL_STATE_TOUCH_SCROLL|| scrollState == SCROLL_STATE_FLING) {isScroll = true;} else {isScroll = false;}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {if (!isScroll) {return;}if (mReady) {String key = getAlpha(totalCityList.get(firstVisibleItem).getKey());overlay.setText(key);overlay.setVisibility(View.VISIBLE);handler.removeCallbacks(overlayThread);// 延迟让overlay为不可见handler.postDelayed(overlayThread, 700);}}
其中最主要关键的地方就是以上这些了
最后我就放上demo的下载地址了,Demo点我
就是这些了,祝大家第一天工作愉快~
-------------------------------
2019-10-09更新
CSDN当初上传设置的最低1分,现在居然涨到50了,,,过分。现在传到了百度云, 提取码:l7ip
欢迎自取,好用的话,不放点个关注。谢谢~~