最近,需要搞一个小功能,仿照美团外卖那种切换城市的小功能,开始觉得还挺简单,但是后来仔细分析还是有点小复杂,但克服困难,参考参考资料也算大功告成了。废话就到这里,然后开始撸代码。

第一步 总想找点资料 ,全国城市的数据库,要是没有还得自己搞数据库,干脆偷下懒直接拿过来用吧(嘿嘿)附件如下 导入到自己的项目中直接使用吧

第二就要写数据库的帮助类了 如下直接贴上代码(主要的部分)注释有的。

// 用户数据库文件的版本
private static final int DB_VERSION = 1;
// 数据库文件目标存放路径为系统默认位置,cn.arthur.examples 是你的包名
private static String DB_PATH = "/data/data/com.baidu.facetoface/databases/";
/*
 * //如果你想把数据库文件存放在SD卡的话 private static String DB_PATH =
 * android.os.Environment.getExternalStorageDirectory().getAbsolutePath() +
 * "/arthurcn/drivertest/packfiles/";
 */
private static String DB_NAME = "meituan_cities.db";
private static String ASSETS_NAME = "meituan_cities.db";
private SQLiteDatabase myDataBase = null;
private final Context myContext;

/**
 * 如果数据库文件较大,使用FileSplit分割为小于1M的小文件 此例中分割为 hello.db.101 hello.db.102
 * hello.db.103
 */
// 第一个文件名后缀
private static final int ASSETS_SUFFIX_BEGIN = 101;
// 最后一个文件名后缀
private static final int ASSETS_SUFFIX_END = 103;

/**
 * SQLiteOpenHelper的子类当中,必须有该构造函数
 *
 * @param context
 *            上下文对象
 * @param name
 *            数据库名称
 * @param factory
 *            一般都是null
 * @param version
 *            当前数据库的版本,值必须是整数并且是递增的状态
 */
public MyDbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
                int version) {// 必须通过super调用父类当中的构造函数
    super(context, name, null, version);
    this.myContext = context;
}public MyDbHelper(Context context, String name, int version) {this(context, name, null, version);
}public MyDbHelper(Context context, String name) {this(context, name, DB_VERSION);
}public MyDbHelper(Context context) {this(context, DB_PATH + DB_NAME);
}public void createDataBase() throws IOException {boolean dbExist = checkDataBase();
    Log.e("database",String.valueOf(dbExist));
    if (dbExist) {// 数据库已存在,do nothing.
    } else {// 创建数据库
        try {File dir = new File(DB_PATH);
            if (!dir.exists()) {dir.mkdirs();
            }File dbf = new File(DB_PATH + DB_NAME);
            if (dbf.exists()) {dbf.delete();
            }SQLiteDatabase.openOrCreateDatabase(dbf, null);
            // 复制asseets中的db文件到DB_PATH下
            copyDataBase();
        } catch (IOException e) {throw new Error("数据库创建失败");
        }}
}// 检查数据库是否有效
private boolean checkDataBase() {SQLiteDatabase checkDB = null;
    String myPath = DB_PATH + DB_NAME;
    try {checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {// database does't exist yet.
    }if (checkDB != null) {checkDB.close();
    }return checkDB != null ? true : false;
}/**
 * Copies your database from your local assets-folder to the just created
 * empty database in the system folder, from where it can be accessed and
 * handled. This is done by transfering bytestream.
 * */
private void copyDataBase() throws IOException {// Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(ASSETS_NAME);
    // Path to the just created empty db
    String outFileName = DB_PATH + DB_NAME;
    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);
    // transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {myOutput.write(buffer, 0, length);
    }// Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
}// 复制assets下的大数据库文件时用这个
private void copyBigDataBase() throws IOException {InputStream myInput;
    String outFileName = DB_PATH + DB_NAME;
    OutputStream myOutput = new FileOutputStream(outFileName);
    for (int i = ASSETS_SUFFIX_BEGIN; i < ASSETS_SUFFIX_END + 1; i++) {myInput = myContext.getAssets().open(ASSETS_NAME + "." + i);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {myOutput.write(buffer, 0, length);
        }myOutput.flush();
        myInput.close();
    }myOutput.close();
}@Override
public synchronized void close() {if (myDataBase != null) {myDataBase.close();
    }super.close();
}

第二步直接使用了创建城市列表 读取数据库然后,进行保存数据。(有的代码截取的不完整,请见谅!)

private ArrayList<City> getCityList() {
    MyDbHelper dbHelper = new MyDbHelper(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;

第三步 地基都准备好了,开始搭房子了。首先分析一下这个界面的实现。

180002d1x1o1sx2vs3o9zf.bmp这个界面从整体上来说包括三大部分第一部分就是最上方的一个EditText,第二部分就是最右边的自定义View,第三部分是EditText下方的ListView,这里EditText的主要作用就是筛选城市,接着我们一点一点的去实现上面的效果。

实现这样一个效果就是滑动最右边的自定义View然后界面中间的TextView去展示所滑到的字母,这里就要去自定义一个View了,首先来分析下思路:

①需要用canvas的drawText方法将:“定位”、最近、热门“、全部、A-Z这些数据画出来,怎么去按照上述图片的样子去绘画这些数据呢?首先需要获得每个字符的高度,怎么获得?用View的高度除以字符的个数就可以得到每个字符的高度,然后绘制时通过控制Y坐标不断的增加从而使数据沿着竖直方向去绘制,在自定义的View中它的实现代码如下

if (showBkg) {//是否显示背景色 触摸后那个阴影效果
    canvas.drawColor(Color.parseColor("#10000000"));
}
int height = getHeight();
int width = getWidth();
int singleHeight = height / b.length;//b 存放字母的数组
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();
}
float xPos = width / 2 - paint.measureText(b[i]) / 2;

就是让所绘制的文字在X方向上显示在View的中间,而float yPos = singleHeight * i + singleHeight;就是来改变每个文字的Y坐标使其沿着竖直方向去绘制文字

在滑动时怎样通知Activity当前滑动到哪儿了?

这里是通过一个监听的方式,在Activity中注册了自定义View的监听,然后在View滑动的时候将数据回调给Activity

这个自定义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 LetterSelectView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);
}public LetterSelectView(Context context, AttributeSet attrs) {super(context, attrs);
}public LetterSelectView(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;//b 存放字母的数组
    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 {void onTouchingLetterChanged(String s);
}

这样右边的效果就实现了。

2、ListView数据的展示

ListView数据的展示是这个界面的重点,对于ListView数据的展示我们都知道它是依靠BaseAdapter的,这里也是通过给ListView设置一个适配器从而实现文章刚开始展现的效果,只不过这里的Adapter用了平时再给ListView设置适配器时不常用的两个方法,一个是getViewTypeCount,另外一个是getItemViewType,仔细观察上面的分析图可以发现这个列表共有5种类型的Item①当前定位城市②最近访问城市③热门城市④全部城市(仅仅显示”全部城市“这四个字)⑤也就是这个列表的主角就是显示从数据库中查出的所有的城市。下面来一一分析这个5种Item的实现方法,

第一种item即当前定位城市,这个item就是用百度定位来定位用户当前所在城市,这个布局没什么可说的。

之前使用百度的地图定位,然而发现这个定位总是实现不了,而且总出现错误找不到文件。浪费好长时间直接换了高德地图定位成功。这个热门城市的类型就一个textView界面不是很好看,如果需要可以使用girdView效果会好看点。下面附上这个adapter的代码。

private LayoutInflater inflater;
private List<City> list;
final int VIEW_TYPE = 3;

public ListAdapter(Context context, List<City> list) {this.inflater = LayoutInflater.from(context);
    this.list = list;
    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 getCount() {return list.size();
}@Override
public Object getItem(int position) {return list.get(position);
}@Override
public long getItemId(int position) {return position;
}@Override
public int getItemViewType(int position) {// TODO Auto-generated method stub
    int type = 0;
    if (position == 0) {type = 2;
    } else if (position == 1) {type = 1;
    }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 (viewType == 1) {if (convertView == null) {topViewHolder = new TopViewHolder();
            convertView = inflater.inflate(R.layout.frist_list_item,
                    null);
            topViewHolder.alpha = (TextView) convertView.findViewById(R.id.alpha);
            topViewHolder.name = (TextView) convertView.findViewById(R.id.lng_city);
            convertView.setTag(topViewHolder);
        } else {topViewHolder = (TopViewHolder) convertView.getTag();
        }/*String locatioName=new Intent().getStringExtra("location");*/
        topViewHolder.name.setText(lngCityName);
       // Log.e("converview",locationName);
        topViewHolder.alpha.setVisibility(View.VISIBLE);
        topViewHolder.alpha.setText("定位城市");

    } else if (viewType == 2) {final ShViewHolder shViewHolder;
        if (convertView == null) {shViewHolder = new ShViewHolder();
            convertView = inflater.inflate(R.layout.search_item, null);
            shViewHolder.editText = (EditText) convertView.findViewById(R.id.sh);
            convertView.setTag(shViewHolder);
        } else {shViewHolder = (ShViewHolder) convertView.getTag();
        }} 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);
                if (currentStr.equals("#")) {currentStr = "热门城市";
                }holder.alpha.setText(currentStr);
            } else {holder.alpha.setVisibility(View.GONE);
            }}}return convertView;

最关键的怎么得到这个city的集合呢 (这个之前的数据库,以及数据库的帮助类要派上用场。)

private ArrayList<City> getCityLists() {MyDbHelper dbHelper = new MyDbHelper(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;
}

从数据中取出城市的数据包括城市 加上城市的拼音然后保存到集合 最后用集合的排序进行A--Z进行排序。

/**
 * 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;
        }}
};

然后 这个本来就该结束了,但是我这个从数据库查询不到信息,数据库存在 然后用  sqlite export 打开进行sql查询发现可以查到数据但是在代码中却发现不了这张表 最后只能发大招(笨人有笨人的方法)手动添加数据到map 然后 从map遍历得到城市 城市拼音 ,最后添加到集合。附上手写的(手快残了感觉)

private ArrayList<City> getCityList() {ArrayList<City> list = new ArrayList<City>();

        Map<String ,String > map =new HashMap<String,String>();
        map.put("北京","beijing");
        map.put("上海","shanghai");
        map.put("广州","guangzhou");
        map.put("深圳","shenzhen");
        map.put("天津","tianjin");
        map.put("西安","xian");
        map.put("福州","fuzhou");
        map.put("重庆","chongqing");
        map.put("杭州","hangzhou");
        map.put("宁波","ningbo");
        map.put("无锡","wuxi");
        map.put("南京","nanjing");
        map.put("合肥","hefei");
        map.put("武汉","wuhan");
        map.put("成都","chengdu");
        map.put("青岛","qingdao");
        map.put("厦门","xiamen");
        map.put("大连","dalian");
        map.put("沈阳","shenyang");
        map.put("长沙","changsha");
        map.put("郑州","zhengzhou");
        map.put("石家庄","shijiazhuang");
        map.put("苏州","suzhou");
        map.put("淄博","zibo");
        map.put("南通","nantong");
        map.put("南昌","nanchang");
        map.put("保定","baoding");
        map.put("蚌埠","bengbu");
        map.put("常州","changzhou");
        map.put("大庆","daqing");
        map.put("东莞","dongguan");
        map.put("佛山","foshan");
        map.put( "桂林","guilin");
        map.put("海口","haikou");
        map.put("葫芦岛","huludao");
        map.put("济南","jinan");
        map.put( "焦作","jiaozuo");
        map.put("锦州","jinzhou");
        map.put("南宁","nanning");
        map.put("太原","taiyuan");
        map.put("芜湖","wuhu");
        map.put("新乡","xinxiang");
        map.put("烟台","yantai");
        map.put("哈尔滨","haerbin");
        map.put("廊坊","langfang");
        map.put("贵阳","guiyang");
        map.put("珠海","zhuhai");
        map.put("齐齐哈尔","qiqihaer");
        map.put("泉州","quanzhou");
        map.put("三亚","sanya");
        map.put("温州","wenzhou");
        map.put( "中山","zhongshan");
        map.put("昆明","kunming");
        map.put("九江","jiujiang");
        map.put("长春","changchun");
        map.put("汕头","shantou");
        map.put("香港","xianggang");
        map.put("徐州","xuzhou");
        map.put("扬州","yangzhou");
        map.put("唐山","tangshan");
        map.put("秦皇岛","qinhuangdao");
        map.put("邯郸","handan");
        map.put("邢台","xingtai");
        map.put("张家口"  ,"zhangjiakou");
        map.put("承德","chengde");
        map.put("沧州","cangzhou");
        map.put("衡水","hengshui");
        map.put("大同","datong");
        map.put("阳泉","yangquan");
        map.put("长治","changzhi");
        map.put("晋城","jincheng");
        map.put("朔州","shuozhou");
        map.put("晋中","jinzhong");
        map.put("运城","yuncheng");
        map.put("忻州","xinzhou");
        map.put("临汾","linfen");
        map.put("吕梁","lvliang");
        map.put("呼和浩特","huhehaote");
        map.put("包头","baotou");
        map.put("乌海","wuhai");
        map.put("赤峰","chifeng");
        map.put("通辽","tongliao");
        map.put("鄂尔多斯","eerduosi");
        map.put("呼伦贝尔","hulunbeier");
        map.put("巴彦淖尔","bayannaoer");
        map.put("乌兰察布","wulanchabu");
        map.put("兴安","xinganmeng");
        map.put("锡林郭勒","xilinguolemeng");
        map.put("阿拉善","alashanmeng");
        map.put("鞍山","anshan");
        map.put("抚顺","fushun");
        map.put("本溪","benxi");
        map.put("丹东","dandong");
        map.put("营口","yingkou");
        map.put("阜新","fuxin");
        map.put("辽阳","liaoyang");
        map.put("盘锦","panjin");
        map.put("铁岭","tieling");
        map.put("朝阳","chaoyang");
        map.put("吉林","jilin");
        map.put("四平","siping");
        map.put("辽源","liaoyuan");
        map.put("通化","tonghua");
        map.put("白山","baishan");
        map.put("松原","songyuan");
        map.put("白城","baicheng");
        map.put("延边","yanbian");
        map.put("鸡西","jixi");
        map.put("鹤岗","hegang");
        map.put("双鸭山"  ,"shuangyashan");
        map.put("伊春","yichun");
        map.put("佳木斯","jiamusi");
        map.put("七台河","qitaihe");
        map.put("牡丹江","mudanjiang");
        map.put("黑河","heihe");
        map.put("绥化","suihua");
        map.put("大兴安岭","daxinganling");
        map.put("连云港","lianyungang");
        map.put("淮安","huaian");
        map.put("盐城","yancheng");
        map.put("镇江","zhenjiang");
        map.put("泰州","taizhou");
        map.put("宿迁","suqian");
        map.put("嘉兴","jiaxing");
        map.put("湖州","huzhou");
        map.put("绍兴","haoxing");
        map.put("金华","jinhua");
        map.put("衢州","quzhou");
        map.put("舟山","zhoushan");
        map.put("台州","taizhou");
        map.put("丽水","lishui");
        map.put("淮南","huainan");
        map.put("马鞍山","maanshan");
        map.put("淮北","huaibei");
        map.put("铜陵","tongling");
        map.put("安庆","anqing");
        map.put("黄山","huangshan");
        map.put("滁州","chuzhou");
        map.put("阜阳","fuyang");
        map.put("宿州","suzhousz");
        map.put("巢湖","chaohu");
        map.put("六安","liuan");
        map.put("亳州","bozhou");
        map.put("池州","chizhou");
        map.put("宣城","xuancheng");
        map.put("莆田","putian");
        map.put("三明","sanming");
        map.put("漳州","zhangzhou");
        map.put("南平","nanping");
        map.put("龙岩","longyan");
        map.put("宁德","ningde");
        map.put("景德镇","jingdezhen");
        map.put("萍乡","pingxiang");
        map.put("新余","xinyu");
        map.put("鹰潭","yingtan");
        map.put("赣州","ganzhou");
        map.put("吉安","jian");
        map.put("宜春","yichun");
        map.put("抚州","fuzhoufz");
        map.put("上饶","shangrao");
        map.put("枣庄","zaozhuang");
        map.put("东营","dongying");
        map.put("潍坊","weifang");
        map.put("济宁","jining");
        map.put("泰安","taian");
        map.put("威海","weihai");
        map.put("日照","rizhao");
        map.put("莱芜","laiwu");
        map.put("临沂","linyi");
        map.put("德州","dezhou");
        map.put("聊城","liaocheng");
        map.put("滨州","binzhou");
        map.put("菏泽","heze");
        map.put("开封","kaifeng");
        map.put("洛阳","luoyang");
        map.put("平顶山","pingdingshan");
        map.put("安阳","anyang");
        map.put("鹤壁","hebi");
        map.put("濮阳","puyang");
        map.put("许昌","xuchang");
        map.put("漯河","luohe");
        map.put("三门峡","sanmenxia");
        map.put("南阳","nanyang");
        map.put("商丘","shangqiu");
        map.put("信阳","xinyang");
        map.put("周口","zhoukou");
        map.put("驻马店","zhumadian");
        map.put("济源","jiyuan");
        map.put("黄石","huangshi");
        map.put("十堰","shiyan");
        map.put("宜昌","yichang");
        map.put("襄阳","xiangyang");
        map.put("鄂州","ezhou");
        map.put("荆门","jingmen");
        map.put("孝感","xiaogan");
        map.put("荆州","jingzhou");
        map.put("黄冈","huanggang");
        map.put("咸宁","xianning");
        map.put("随州","suizhou");
        map.put( "恩施", "enshi");
        map.put("三峡","sanxia");
        map.put("株洲","zhuzhou");
        map.put("湘潭","xiangtan");
        map.put("衡阳","hengyang");
        map.put("邵阳","shaoyang");
        map.put("岳阳","yueyang");
        map.put("常德","changde");
        map.put("张家界"  ,"zhangjiajie");
        map.put("益阳","yiyang");
        map.put("郴州","chenzhou");
        map.put("永州","yongzhou");
        map.put("怀化","huaihua");
        map.put("娄底",  "loudi");
        map.put("湘西",  "xiangxi");
        map.put("韶关",  "shaoguan");
        map.put("江门"   ,"jiangmen");
        map.put("湛江",  "zhanjiang");
        map.put("茂名",  "maoming");
        map.put("肇庆","zhaoqing");
        map.put("惠州","huizhou");
        map.put("梅州","meizhou");
        map.put("汕尾","shanwei");
        map.put("河源","heyuan");
        map.put("阳江",  "yangjiang");
        map.put("清远",  "qingyuan");
        map.put("潮州","chaozhou");
        map.put("揭阳","jieyang");
        map.put("云浮","yunfu");
        map.put("柳州","liuzhou");
        map.put("梧州","wuzhou");
        map.put("北海",  "beihai");
        map.put("防城港","fangchenggang");
        map.put("钦州","qinzhou");
        map.put("贵港","guigang");
        map.put("玉林","yulin");
        map.put("百色","baise");
        map.put("贺州","hezhou");
        map.put("河池","hechi");
        map.put("来宾","laibin");
        map.put("崇左","chongzuo");
        map.put("自贡","zigong");
        map.put("攀枝花","panzhihua");
        map.put("泸州","luzhou");
        map.put("德阳","deyang");
        map.put("绵阳","mianyang");
        map.put("广元","guangyuan");
        map.put("遂宁","suining");
        map.put("内江","neijiang");
        map.put("乐山","leshan");
        map.put("南充","nanchong");
        map.put("眉山","meishan");
        map.put("宜宾","yibin");
        map.put("广安","guangan");
        map.put("达州","dazhou");
        map.put("雅安","yaan");
        map.put("巴中","bazhong");
        map.put("资阳","ziyang");
        map.put("阿坝","aba");
        map.put("甘孜","ganzi");
        map.put("凉山","liangshan");
        map.put("六盘水","liupanshui");
        map.put("遵义","zunyi");
        map.put("安顺","anshun");
        map.put("铜仁","tongren");
        map.put("黔西南","qianxinan");
        map.put("毕节","bijiediqu");
        map.put("黔东南","qiandongnan");
        map.put("黔南","qiannan");
        map.put("曲靖","qujing");
        map.put("玉溪","yuxi");
        map.put("保山","baoshan");
        map.put("昭通","zhaotong");
        map.put("丽江","lijiang");
        map.put("普洱","puer");
        map.put("临沧","lincang");
        map.put("楚雄","chuxiong");
        map.put( "红河","honghe");
        map.put("文山","wenshan");
        map.put("西双版纳","xishuangbanna");
        map.put("大理","dali");
        map.put("德宏","dehong");
        map.put( "怒江","nujiang");
        map.put("迪庆","diqing");
        map.put( "拉萨","lasa");
        map.put("昌都","changdu");
        map.put("山南","shannan");
        map.put("日喀则","rikaze");
        map.put("那曲","naqu");
        map.put("阿里","ali");
        map.put("林芝","linzhi");
        map.put("铜川","tongchuan");
        map.put("宝鸡","baoji");
        map.put("咸阳","xianyang");
        map.put("渭南","weinan");
        map.put("延安","yanan");
        map.put("汉中","hanzhong");
        map.put("榆林","yulinyl");
        map.put("安康","ankang");
        map.put("商洛","shangluo");
        map.put("兰州","lanzhou");
        map.put("金昌","jinchang");
        map.put("白银","baiyin");
        map.put("天水","tianshui");
        map.put("武威","wuwei");
        map.put("张掖","zhangye");
        map.put("平凉","pingliang");
        map.put("酒泉","jiuquan");
        map.put("庆阳","qingyang");
        map.put("定西","dingxi");
        map.put("陇南","longnan");
        map.put("临夏","linxia");
        map.put("甘南","gannan");
        map.put("西宁","xining");
        map.put("海东","haidong");
        map.put("海北","haibei");
        map.put("黄南","huangnan");
        map.put("海南州","hainanzhou");
        map.put("果洛","guoluo");
        map.put("玉树","yushu");
        map.put("海西","haixi");
        map.put("银川","yinchuan");
        map.put("石嘴山","shizuishan");
        map.put("吴忠","wuzhong");
        map.put("固原","guyuan");
        map.put("中卫","zhongwei");
        map.put("乌鲁木齐","wulumuqi");
        map.put("克拉玛依","kelamayi");
        map.put("吐鲁番","tulufan");
        map.put("哈密","hami");
        map.put("昌吉","changji");
        map.put("博尔塔拉","boertala");
        map.put("巴州","bazhou");
        map.put("阿克苏","akesu");
        map.put("克州","kezhou");
        map.put("喀什","kashi");
        map.put("和田","hetian");
        map.put("伊犁","yili");
        map.put("塔城","tacheng");
        map.put("阿勒泰","aletai");
        map.put("台北","taibei");
        map.put("澳门","aomen");
        map.put("昆山","kunshan");
        map.put("江阴","jiangyin");
        map.put("义乌","yiwu");
        map.put("顺德","shunde");
        map.put("石河子","shihezi");
        map.put("嘉峪关","jiayuguan");
        map.put("花都","huadu");
        map.put("番禺","panyu");
        map.put("仙桃","xiantao");
        map.put("富阳","fuyangfy");
        map.put("峨眉山","emeishan");
        map.put("琼海","qionghai");
        map.put("张家港"  ,"zhangjiagang");
        map.put("晋江","jinjiang");
        map.put("从化","conghua");
        map.put("常熟","changshu");
        map.put("延吉","yanji");
        map.put("海宁","haining");
        map.put("桐乡","tongxiang");
        map.put("涿州","zhuozhou");
        map.put("涪陵","fuling");
        map.put("万州","wanzhou");
        map.put("江宁","jiangning");
        map.put("迁安","qianan");
        map.put("丹阳","danyang");
        map.put("太仓","taicang");
        map.put("吴江","wujiang");
        map.put("敦煌","dunhunag");
        map.put("塘沽","tanggu");
        map.put("靖江","jingjiang");
        map.put("石狮","shishi");
        map.put("武夷山","wuyishan");
        map.put("萧山","xiaoshan");

        Iterator it   =   map.entrySet().iterator()   ;
        while   (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();
            String  key =(String) entry.getKey();
            String value = (String) entry.getValue();
            City city = new City(key, value);
            list.add(city);
        }Collections.sort(list, comparator);
    return list;
}

差点废了。。。 最后圆满完成。感谢各位观看。最后需要详细源码的同学请在评论去留下邮箱,

android 仿美团选择城市界面相关推荐

  1. Android 仿美团选择城市、微信通讯录、饿了么点餐列表的导航悬停分组索引列表

    SuspensionIndexBar 项目地址:mcxtzhang/SuspensionIndexBar 简介:快速实现分组悬停.右侧索引导航联动 列表. 如 美团选择城市界面,微信通讯录界面.饿了么 ...

  2. 【Android】快速实现仿美团选择城市界面,微信通讯录界面

    概述 本文是这个系列的第三篇,不出意外也是终结篇.因为使用经过重构后的控件已经可以快速实现市面上带 索引导航.悬停分组的列表界面了. 在前两篇里,我们从0开始,一步一步实现了仿微信通讯录.饿了么选餐界 ...

  3. Android仿美团选择城市

    需求:需要有当前定位城市,热门城市,下面按照城市首拼音排序,滑动的过程中字母A,B,C-会置顶互相切换.右侧有快速切换字母城市的选择 效果图: 思路:因为上部分要划走,RecyclerView滑动过程 ...

  4. Android仿美团切换城市

    转载请注明出处:http://blog.csdn.net/dmk877/article/details/49757731 最近一直关注一些比较有名的app,像美团.58.赶集网.淘宝等等.主要目的就是 ...

  5. [Android精品源码] Android 仿美团网,探索ListView的A-Z字母排序功能实现选择城市

    Material Design中文版Code4APPPHP100UI4APP 开启辅助访问设为首页收藏本站快捷导航切换到宽版切换风格 石刚 | |我的 |签到打卡 |设置 |消息 |提醒(2) |退出 ...

  6. Android上实现一个简单的天气预报APP(七) 切换到新的界面(选择城市界面)

    学习参考资源:https://www.gitbook.com/book/zhangqx/mini-weather/details 前面我们已经设置好了基本界面,并可以从网络上实时获取天气预报信息并解析 ...

  7. android 美团下拉菜单,Android仿美团分类下拉菜单实例代码

    本文实例为大家分享了Android仿美团下拉菜单的实现代码,分类进行选择,供大家参考,具体内容如下 效果图 操作平台 AS2.0 第三方框架:butterknife build.gradle depe ...

  8. 仿美团外卖菜单界面的实现

    仿美团外卖菜单界面的实现 布局文件 总布局 <?xml version="1.0" encoding="utf-8"?> <LinearLay ...

  9. Android仿微信气泡聊天界面设计

    Android仿微信气泡聊天界面设计 微信的气泡聊天是仿iPhone自带短信而设计出来的,不过感觉还不错可以尝试一下仿着微信的气泡聊天做一个Demo,给大家分享一下!效果图如下: 气泡聊天最终要的是素 ...

  10. Android仿IOS解锁密码界面-自定义view系列(6)

    Android仿IOS解锁密码界面-自定义view系列 功能简介 主要实现步骤-具体内容看github项目里的代码 xml相关属性设置 Android Studio 代码 Android技术生活交流 ...

最新文章

  1. Colly源码解析——框架
  2. 在JavaScript中深度克隆对象的最有效方法是什么?
  3. type和object
  4. LaTeX写作技术规范
  5. MSSQL Server 导入/导出到远程服务器
  6. SQL -- 多表查询
  7. mysql表变量临时表_表变量和临时表详解
  8. oracle基表恢复,查找V$PARAMETER 基表 – 专业Oracle数据库恢复,或许是您恢复数据的最后机会@phone:13429648788 - 专业Oracle数据库恢复技术支持...
  9. 原来它一直在“装嫩”|“心电图”揭秘富锂巨星真实年龄
  10. [转]PHP 超全局变量详解 $GLOBALS $_SERVER $_GET $_POST $_COOKIE $_FILES $_ENV $_REQUEST $_SE
  11. JavaScript学习(四十七)—构造方法创建对象的不足
  12. Linux 命令(52)—— ipcrm 命令
  13. 手机端html本地存储,HTML5 web storage本地存储
  14. Hinton神经网络公开课16 Recent applications of deep neural nets
  15. 如何免费下载DEM数据
  16. java动作游戏教程_格斗游戏的动作设计和制作
  17. 百度地图API之根据经纬度查询地址信息(Android) .(10)
  18. 代理(proxy):正向代理,反向代理
  19. pg_restore恢复备份(记录一下)
  20. GB28181平台如何接入无人机实现智能巡检?

热门文章

  1. Android开发知识(十二):30分钟快速接入微信支付SDK
  2. “新”科学家Stephen Wolfram
  3. 万树IT:怎样能快速学会开发安卓 App
  4. 5G NR - RLC协议阅读笔记5 - RLC AMD PDU接收过程
  5. 目标检测之分类、回归和损失函数
  6. oracle日期加1天
  7. 电子签约系统:解决组织异地用章难题
  8. 关于前端应用表现层抽象--学习笔记
  9. 量化软件哪家好(免费的量化交易软件
  10. Maven报警:No archetype found in remote catalog. Defaulting to internal catalog.