12

Android仿美团切换城市

 3 years ago
source link: https://blog.csdn.net/dmk877/article/details/49757731
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Android仿美团切换城市_dmk877的专栏-CSDN博客_android 仿美团城市选择

        转载请注明出处:http://blog.csdn.net/dmk877/article/details/49757731

     最近一直关注一些比较有名的app,像美团、58、赶集网、淘宝等等。主要目的就是学习下目前一些常用的技术,模拟一下它们的比较炫的界面来巩固下知识,我发现美团、58同城、赶集网它们的切换城市界面类似,也挺酷炫,另外一个原因由于前面几篇博客写的自定义控件的一些知识相对来说比较难,也有好多看官反应很难读懂,那么好,今天呢,就和大家一起分享一下这个界面的写法。这个界面的实现并不难牵扯到的知识点还挺多的而且还挺酷炫,所以能够读这篇博客你绝对赚到了,哈哈。。。

如有谬误欢迎批评指正,如有疑问欢迎留言。

通过本篇博客你将学到以下知识点

①BaseAdapter的使用包括BaseAdapter中的getViewTypeCount和getItemViewType方法的使用

②百度地图定位的使用

③自定义控件的相关的知识

④数据库相关的操作

⑤pinyin4j的用法

我们废话不多说先看看效果图这也是今天我们要达到的效果,由于csdn只允许上传图片大小不超过2M的图片,所以这里我录制两张图片如下

Center
        
Center

它的主要功能有:①展示定位的城市②展示最近访问的城市③展示热门的城市④展示需要展示的城市⑤用EditText进行筛选城市⑥当滑动右边的字母时左边的ListView会跳到相应的位置等。

在这里要提醒大家注意一点不要在模拟器上运行,最好在真机上运行,模拟器上的运行界面效果不好,看到上面两张图是不是感觉还不错,通过这篇博客的学习相信你也可以,咱们废话不多说进入主题

首先来分析下整个界面如下图

Center

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

1、右侧自定义View的实现

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

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

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

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

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

我们先看看代码然后运行下看看是不是这样

MyLetterView的代码如下

可以发现重写了onTouchEvent方法,然后通过监听down,move,up事件来执行相关的操作,当down时首先会改变整个view的背景色,然后将当前滑到的字母通过回调的方式即调用mOnSlidingListener.sliding(letter[position])(这里的mOnSlidingListener就是在activity中的setOnSlidingListener所注册的监听器)传递到Activity中。

MainActivity中的代码

在MAinActivity中可以看到myLetterView注册了在MyLetterView中的监听,通过回调的方式将MyLetterView中滑动到的文字传递给MainAcitivity中,并通过tvDialog显示在屏幕中间,它的效果图如下

Center

可以看到效果还不错,(再次提醒注意这里最好不要用模拟器去运行,因为模拟器上运行的效果与和上面的效果差距很大,用真机效果好)这样自定义的这个View的功能就实现了。

2、ListView数据的展示

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

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

第二种布局即最近访问城市,认真看文章刚开始的那个分析图会发现这个item包含一个GridView用来展示最近访问的城市,这里需要注意美团它的最近访问城市是展示三个,我们这里也是,这里的最近访问城市是通过操作数据库来实现的,这里有两种实现方法①当数据库中已经有三条数据时,当用户访问第四个城市的时候,此时需要将第四个城市插入到最近访问城市的最前面,而将数据库中原来排在第三位的城市删除掉,这样就保证了数据库中始终有三个最近访问的城市。②每次都将新访问的城市插入到数据库,在查询时只查前三条,并按时间先后顺序排序。这里我们采用的是第2个方案,它的实现代码如下

查询城市

如果你对数据库不熟可以参考此博客 SQLiteDatabase数据库操作详解

第三种布局即热门城市这个item和第二种类似,也是包含一个GridView这里的GridView的数据是从服务器中返回过来的,这里需要注意的是这里的GridView和第二种布局中的GridView都是自定义的GridView,因为这里的GridView是以Item的形式展现在ListView中的,所以当数据较多时GridView的数据展示不完,这里进行自定义的目的在于,GridView的数据有多少我们让它自适应数据的个数不需要滑动而将数据展示完。它的定义也非常简单代码如下

如果大家对自定义View不熟可以参考此博客( Android开发之自定义控件(一)---onMeasure详解)

第四种布局很简单就是一个TextView展示“全部城市”这四个字

第五种布局也就是主角的主角,就是按照字母的顺序去展示从数据库中查出来的城市,这里的数据是在assets下的一个db文件通过调用SQLiteDatabase.openOrCreateDatabase(dbf, null)在android中使用SQLiteDatabase的静态方法openOrCreateDatabase(String  path,SQLiteDatabae.CursorFactory  factory)(参数1 :数据库创建的路径,参数2 :一般设置为null就可以了)打开或者创建一个数据库。它会自动去检测是否存在这个数据库,如果存在则打开,不存在则创建一个数据库;创建成功则返回一个SQLiteDatabase对象,否则抛出异常FileNotFoundException,例如创建一个meituan_cities.db的数据库

 ,SQLiteDatabae db=SQLiteDatabase.openOrCreateDatabase("/data/data/com.lingdududu.db/databases/meituan_cities.db",null); 在这个项目中这里的“/data/data/com.lingdududu.db/databases/meituan_cities.db”就是项目的assets目录下的meituan_cities.db的路径。

如果你仔细看了这个界面你会发现这里的城市被分成了22组,哪22组?从A-Z 26个字母去掉i,o,u,v。这一点可以从我们刚才自定义的View的字母中看到,如果我没说之前你发现了,我只能说你太牛逼了,你可以去警察局破案了,哈哈。每一组的第一个Item是展示这组数据的首字母的。这是怎么做到的呢?这就需要依靠pinyin4j这个jar包了,如果你不会用可以去查查资料,这里我们的代码里也有详细的注释,由于篇幅原因我就不再说了,如果有需要的话我会专门写一篇博客来阐述它的用法。这里说一下它的实现思想,它是通过当前条目的城市的拼音的首字母和它的前一个条目的城市的拼音的首字母进行比较,如果不相同说明这是下一组的数据,当前条目应该展示首字母,否则的话就将展示字母的TextView隐藏起来。

好了将这5种类型的Item都分析完后我们来看看,它的部分代码

将字母按A-Z排序的comparator

在MainActivity中将查询出来的数据按照我们自己定义的规则进行排序的代码如下

Collections.sort(cityList, comparator);

创建数据库的代码

创建好数据库后将assets下的数据复制到创建好的数据库下copyDataBase方法的代码如下

ListView的Adapter的代码

    里面用到了百度的定位,里面的注释都很清楚就不多说了,这里说一下这样一个功能的实现,这个功能是当滑动右边的自定义的View时,ListView根据当前滑动的字母进行变动,这是怎么实现的?它的实现的思想是这样的,将上面说的22组数据中,每一组的第一个条目的城市的首字母(也就是在ListView中显示字母的那个条目)以key,value的形式放到Map中,这里的key就是当前展示的字母,而value是当前条目在整个列表集合的位置,注意这里的集合是ListView展示的所有数据的集合,包括我们所说的5种布局的全部数据的集合。而当滑动右边的自定义的View时,假如说滑动到了“S”,这时在MainActivity中有个回调会将当前滑动的字母回调到MainActivity中,在MainAcivity中收到当前滑动到的“S”后,就会从Map中根据这个字母来查询它在ListView中所对应的位置,然后通过ListView.setSelection(position)这个方法使界面显示与当前字母所对应的那个组。它的实现代码如下

3、EditText实现筛选城市的功能

     这个功能的实现其实很简单,在MainAcitivity中其实是有两个ListView的一个就是用来展示所有的数据用的,另外一个就是用来展示搜索结果用的,这里实现筛选的方式很简单就是给EditText添加一个addTextChangedListener,这个监听器的代码如下

当输入内容时会把展示数据的ListView进行隐藏,而把展示搜索结果的ListView显示出来,根据EditText输入的内容,从数据库中筛选出来符合条件的数据进行展示,它的筛选的SQL语句如下

Cursor cursor = db.rawQuery("select * from city where name like \"%" + keyword+ "%\" or pinyin like \"%" + keyword + "%\"", null);
然后将筛选出来的数据通过Adapter展示出来,这样就完成这个功能。

到这里关于仿58,美团,赶集网的切换城市的界面就算写完了,里面由于细节特别多,我就捡主要的功能,分析了它的实现思想。

如果你有什么疑问,或者发现文章中的错误,欢迎批评指正,谢谢。如果你觉着这篇文章对你有帮助,就赞一个,顶一下呗,您的支持是我前进的动力。。

源码地址

或者加群,群里有源码。群号:467325240

 转载请注明出处:http://blog.csdn.net/dmk877/article/details/49757731


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK