├── .gitignore
├── CityList
├── .classpath
├── .project
├── .settings
│ └── org.eclipse.core.resources.prefs
├── AndroidManifest.xml
├── bin
│ ├── AndroidManifest.xml
│ ├── CityList.apk
│ ├── classes.dex
│ ├── classes
│ │ └── com
│ │ │ └── liucanwen
│ │ │ └── citylist
│ │ │ ├── BuildConfig.class
│ │ │ ├── MainActivity$1.class
│ │ │ ├── MainActivity$SearchListTask.class
│ │ │ ├── MainActivity.class
│ │ │ ├── R$attr.class
│ │ │ ├── R$color.class
│ │ │ ├── R$dimen.class
│ │ │ ├── R$drawable.class
│ │ │ ├── R$id.class
│ │ │ ├── R$layout.class
│ │ │ ├── R$menu.class
│ │ │ ├── R$string.class
│ │ │ ├── R$style.class
│ │ │ ├── R.class
│ │ │ ├── adapter
│ │ │ └── CityAdapter.class
│ │ │ ├── data
│ │ │ └── CityData.class
│ │ │ ├── model
│ │ │ └── CityItem.class
│ │ │ └── widget
│ │ │ ├── ContactItemComparator.class
│ │ │ ├── ContactItemException.class
│ │ │ ├── ContactItemInterface.class
│ │ │ ├── ContactListAdapter.class
│ │ │ ├── ContactListView$1.class
│ │ │ ├── ContactListView.class
│ │ │ ├── ContactListViewImpl.class
│ │ │ ├── ContactsSectionIndexer.class
│ │ │ ├── IndexScroller$1.class
│ │ │ ├── IndexScroller.class
│ │ │ └── pinyin
│ │ │ ├── HanziToPinyin3$Token.class
│ │ │ ├── HanziToPinyin3.class
│ │ │ └── PinYin.class
│ ├── dexedLibs
│ │ └── android-support-v4-067dccf2020c5ee1f85b6c06df5b91ca.jar
│ ├── res
│ │ ├── drawable-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── icon_search.png
│ │ │ ├── line.9.png
│ │ │ ├── search_bg.9.png
│ │ │ └── search_puin.9.png
│ │ ├── drawable-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ │ └── ic_launcher.png
│ │ └── drawable-xxhdpi
│ │ │ └── ic_launcher.png
│ └── resources.ap_
├── gen
│ └── com
│ │ └── liucanwen
│ │ └── citylist
│ │ ├── BuildConfig.java
│ │ └── R.java
├── ic_launcher-web.png
├── libs
│ └── android-support-v4.jar
├── proguard-project.txt
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ ├── ic_launcher.png
│ │ ├── icon_search.png
│ │ ├── line.9.png
│ │ ├── listitem_selector.xml
│ │ ├── search_bg.9.png
│ │ └── search_puin.9.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── activity_main.xml
│ │ └── city_item.xml
│ ├── menu
│ │ └── main.xml
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── color.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── liucanwen
│ └── citylist
│ ├── MainActivity.java
│ ├── adapter
│ └── CityAdapter.java
│ ├── data
│ └── CityData.java
│ ├── model
│ └── CityItem.java
│ └── widget
│ ├── ContactItemComparator.java
│ ├── ContactItemException.java
│ ├── ContactItemInterface.java
│ ├── ContactListAdapter.java
│ ├── ContactListView.java
│ ├── ContactListViewImpl.java
│ ├── ContactsSectionIndexer.java
│ ├── IndexScroller.java
│ └── pinyin
│ ├── HanziToPinyin3.java
│ └── PinYin.java
├── README.md
├── all_screenshot.jpg
├── screenshot1.png
├── screenshot2.png
└── screenshot3.png
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Package Files #
4 | *.jar
5 | *.war
6 | *.ear
7 |
--------------------------------------------------------------------------------
/CityList/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CityList/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | CityList
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/CityList/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding//src/com/liucanwen/citylist/widget/pinyin/HanziToPinyin3.java=UTF-8
3 | encoding//src/com/liucanwen/citylist/widget/pinyin/PinYin.java=UTF-8
4 |
--------------------------------------------------------------------------------
/CityList/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/CityList/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/CityList/bin/CityList.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/CityList.apk
--------------------------------------------------------------------------------
/CityList/bin/classes.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes.dex
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/BuildConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/BuildConfig.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/MainActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/MainActivity$1.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/MainActivity$SearchListTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/MainActivity$SearchListTask.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/MainActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/MainActivity.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$attr.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$color.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$color.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$dimen.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$dimen.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$drawable.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$id.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$layout.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$layout.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$menu.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$menu.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$string.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R$style.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R$style.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/R.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/adapter/CityAdapter.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/adapter/CityAdapter.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/data/CityData.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/data/CityData.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/model/CityItem.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/model/CityItem.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactItemComparator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactItemComparator.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactItemException.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactItemException.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactItemInterface.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactItemInterface.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListAdapter.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListAdapter.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListView$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListView$1.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListView.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListView.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListViewImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactListViewImpl.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/ContactsSectionIndexer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/ContactsSectionIndexer.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/IndexScroller$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/IndexScroller$1.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/IndexScroller.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/IndexScroller.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/pinyin/HanziToPinyin3$Token.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/pinyin/HanziToPinyin3$Token.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/pinyin/HanziToPinyin3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/pinyin/HanziToPinyin3.class
--------------------------------------------------------------------------------
/CityList/bin/classes/com/liucanwen/citylist/widget/pinyin/PinYin.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/classes/com/liucanwen/citylist/widget/pinyin/PinYin.class
--------------------------------------------------------------------------------
/CityList/bin/dexedLibs/android-support-v4-067dccf2020c5ee1f85b6c06df5b91ca.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/dexedLibs/android-support-v4-067dccf2020c5ee1f85b6c06df5b91ca.jar
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-hdpi/icon_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-hdpi/icon_search.png
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-hdpi/line.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-hdpi/line.9.png
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-hdpi/search_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-hdpi/search_bg.9.png
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-hdpi/search_puin.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-hdpi/search_puin.9.png
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/bin/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/bin/resources.ap_:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/bin/resources.ap_
--------------------------------------------------------------------------------
/CityList/gen/com/liucanwen/citylist/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package com.liucanwen.citylist;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/CityList/gen/com/liucanwen/citylist/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.liucanwen.citylist;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class color {
14 | public static final int background=0x7f040000;
15 | public static final int black=0x7f040001;
16 | public static final int bulegray=0x7f040006;
17 | public static final int divider_line=0x7f040012;
18 | public static final int font_focus=0x7f04000f;
19 | public static final int gold=0x7f04000b;
20 | public static final int gold_player=0x7f040010;
21 | public static final int gray=0x7f040007;
22 | public static final int graylight=0x7f040008;
23 | public static final int listview_item_normal=0x7f040013;
24 | public static final int listview_item_pressed=0x7f040014;
25 | public static final int message_checked=0x7f040015;
26 | public static final int message_no_check=0x7f040016;
27 | public static final int nearly_hard=0x7f04000e;
28 | public static final int orange=0x7f040009;
29 | public static final int orange_light=0x7f04000a;
30 | public static final int pink_red=0x7f040004;
31 | public static final int red=0x7f040005;
32 | public static final int semitransparent=0x7f04000d;
33 | public static final int stick_color_bg=0x7f040017;
34 | public static final int transparent=0x7f04000c;
35 | public static final int white=0x7f040002;
36 | public static final int whitetran=0x7f040011;
37 | public static final int yellow=0x7f040003;
38 | }
39 | public static final class dimen {
40 | /** Default screen margins, per the Android Design guidelines.
41 |
42 | Customize dimensions originally defined in res/values/dimens.xml (such as
43 | screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
44 |
45 | */
46 | public static final int activity_horizontal_margin=0x7f050000;
47 | public static final int activity_vertical_margin=0x7f050001;
48 | }
49 | public static final class drawable {
50 | public static final int ic_launcher=0x7f020000;
51 | public static final int icon_search=0x7f020001;
52 | public static final int line=0x7f020002;
53 | public static final int listitem_selector=0x7f020003;
54 | public static final int search_bg=0x7f020004;
55 | public static final int search_puin=0x7f020005;
56 | }
57 | public static final class id {
58 | public static final int action_settings=0x7f090007;
59 | public static final int button_search=0x7f090002;
60 | public static final int cityName=0x7f090006;
61 | public static final int infoRowContainer=0x7f090005;
62 | public static final int input_search_query=0x7f090001;
63 | public static final int listview=0x7f090003;
64 | public static final int searchBarContainer=0x7f090000;
65 | public static final int sectionTextView=0x7f090004;
66 | }
67 | public static final class layout {
68 | public static final int activity_main=0x7f030000;
69 | public static final int city_item=0x7f030001;
70 | }
71 | public static final class menu {
72 | public static final int main=0x7f080000;
73 | }
74 | public static final class string {
75 | public static final int action_settings=0x7f060001;
76 | public static final int app_name=0x7f060000;
77 | public static final int hello_world=0x7f060002;
78 | }
79 | public static final class style {
80 | /**
81 | Base application theme, dependent on API level. This theme is replaced
82 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
83 |
84 |
85 | Theme customizations available in newer API levels can go in
86 | res/values-vXX/styles.xml, while customizations related to
87 | backward-compatibility can go here.
88 |
89 |
90 | Base application theme for API 11+. This theme completely replaces
91 | AppBaseTheme from res/values/styles.xml on API 11+ devices.
92 |
93 | API 11 theme customizations can go here.
94 |
95 | Base application theme for API 14+. This theme completely replaces
96 | AppBaseTheme from BOTH res/values/styles.xml and
97 | res/values-v11/styles.xml on API 14+ devices.
98 |
99 | API 14 theme customizations can go here.
100 | */
101 | public static final int AppBaseTheme=0x7f070000;
102 | /** Application theme.
103 | All customizations that are NOT specific to a particular API-level can go here.
104 | */
105 | public static final int AppTheme=0x7f070001;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/CityList/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/ic_launcher-web.png
--------------------------------------------------------------------------------
/CityList/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/CityList/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/CityList/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 |
--------------------------------------------------------------------------------
/CityList/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/res/drawable-hdpi/icon_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-hdpi/icon_search.png
--------------------------------------------------------------------------------
/CityList/res/drawable-hdpi/line.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-hdpi/line.9.png
--------------------------------------------------------------------------------
/CityList/res/drawable-hdpi/listitem_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/CityList/res/drawable-hdpi/search_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-hdpi/search_bg.9.png
--------------------------------------------------------------------------------
/CityList/res/drawable-hdpi/search_puin.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-hdpi/search_puin.9.png
--------------------------------------------------------------------------------
/CityList/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CityList/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
28 |
29 |
40 |
41 |
42 |
46 |
47 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/CityList/res/layout/city_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
19 |
20 |
27 |
28 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/CityList/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/CityList/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/CityList/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
--------------------------------------------------------------------------------
/CityList/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/CityList/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/CityList/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FF000000
5 | #FF000000
6 | #FFFFFFFF
7 | #FFFFE400
8 | #F63E2A
9 | #FF0000
10 | #f0f0f0
11 | #828282
12 | #cccccc
13 | #FF6600
14 | #fdaa0b
15 | #ffd700
16 | #00000000
17 | #90000000
18 | #97000000
19 | #D7F679
20 | #F7F466
21 | #87FFFFFF
22 | #FF575757
23 |
24 | #eef0ed
25 | #d4d4d4
26 |
27 | #90918f
28 | #323232
29 |
30 | #e2e2e2
31 |
32 |
33 |
--------------------------------------------------------------------------------
/CityList/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/CityList/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CityList
5 | Settings
6 | Hello world!
7 |
8 |
--------------------------------------------------------------------------------
/CityList/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.app.Activity;
7 | import android.content.Context;
8 | import android.os.AsyncTask;
9 | import android.os.Bundle;
10 | import android.text.Editable;
11 | import android.text.TextWatcher;
12 | import android.util.Log;
13 | import android.view.View;
14 | import android.widget.AdapterView;
15 | import android.widget.EditText;
16 | import android.widget.Toast;
17 |
18 | import com.liucanwen.citylist.adapter.CityAdapter;
19 | import com.liucanwen.citylist.data.CityData;
20 | import com.liucanwen.citylist.model.CityItem;
21 | import com.liucanwen.citylist.widget.ContactItemInterface;
22 | import com.liucanwen.citylist.widget.ContactListViewImpl;
23 |
24 | public class MainActivity extends Activity implements TextWatcher
25 | {
26 | private Context context_ = MainActivity.this;
27 |
28 | private ContactListViewImpl listview;
29 |
30 | private EditText searchBox;
31 | private String searchString;
32 |
33 | private Object searchLock = new Object();
34 | boolean inSearchMode = false;
35 |
36 | private final static String TAG = "MainActivity2";
37 |
38 | List contactList;
39 | List filterList;
40 | private SearchListTask curSearchTask = null;
41 |
42 | @Override
43 | public void onCreate(Bundle savedInstanceState)
44 | {
45 | super.onCreate(savedInstanceState);
46 | setContentView(R.layout.activity_main);
47 |
48 | filterList = new ArrayList();
49 | contactList = CityData.getSampleContactList();
50 |
51 | CityAdapter adapter = new CityAdapter(this,
52 | R.layout.city_item, contactList);
53 |
54 | listview = (ContactListViewImpl) this.findViewById(R.id.listview);
55 | listview.setFastScrollEnabled(true);
56 | listview.setAdapter(adapter);
57 |
58 | listview.setOnItemClickListener(new AdapterView.OnItemClickListener()
59 | {
60 | @Override
61 | public void onItemClick(AdapterView parent, View v, int position,
62 | long id)
63 | {
64 | List searchList = inSearchMode ? filterList
65 | : contactList;
66 |
67 | Toast.makeText(context_,
68 | searchList.get(position).getDisplayInfo(),
69 | Toast.LENGTH_SHORT).show();
70 | }
71 | });
72 |
73 | searchBox = (EditText) findViewById(R.id.input_search_query);
74 | searchBox.addTextChangedListener(this);
75 | }
76 |
77 | @Override
78 | public void afterTextChanged(Editable s)
79 | {
80 | searchString = searchBox.getText().toString().trim().toUpperCase();
81 |
82 | if (curSearchTask != null
83 | && curSearchTask.getStatus() != AsyncTask.Status.FINISHED)
84 | {
85 | try
86 | {
87 | curSearchTask.cancel(true);
88 | } catch (Exception e)
89 | {
90 | Log.i(TAG, "Fail to cancel running search task");
91 | }
92 |
93 | }
94 | curSearchTask = new SearchListTask();
95 | curSearchTask.execute(searchString);
96 | }
97 |
98 | @Override
99 | public void beforeTextChanged(CharSequence s, int start, int count,
100 | int after)
101 | {
102 | }
103 |
104 | @Override
105 | public void onTextChanged(CharSequence s, int start, int before, int count)
106 | {
107 | // do nothing
108 | }
109 |
110 | private class SearchListTask extends AsyncTask
111 | {
112 |
113 | @Override
114 | protected String doInBackground(String... params)
115 | {
116 | filterList.clear();
117 |
118 | String keyword = params[0];
119 |
120 | inSearchMode = (keyword.length() > 0);
121 |
122 | if (inSearchMode)
123 | {
124 | // get all the items matching this
125 | for (ContactItemInterface item : contactList)
126 | {
127 | CityItem contact = (CityItem) item;
128 |
129 | boolean isPinyin = contact.getFullName().toUpperCase()
130 | .indexOf(keyword) > -1;
131 | boolean isChinese = contact.getNickName().indexOf(keyword) > -1;
132 |
133 | if (isPinyin || isChinese)
134 | {
135 | filterList.add(item);
136 | }
137 |
138 | }
139 |
140 | }
141 | return null;
142 | }
143 |
144 | protected void onPostExecute(String result)
145 | {
146 |
147 | synchronized (searchLock)
148 | {
149 |
150 | if (inSearchMode)
151 | {
152 |
153 | CityAdapter adapter = new CityAdapter(context_,
154 | R.layout.city_item, filterList);
155 | adapter.setInSearchMode(true);
156 | listview.setInSearchMode(true);
157 | listview.setAdapter(adapter);
158 | } else
159 | {
160 | CityAdapter adapter = new CityAdapter(context_,
161 | R.layout.city_item, contactList);
162 | adapter.setInSearchMode(false);
163 | listview.setInSearchMode(false);
164 | listview.setAdapter(adapter);
165 | }
166 | }
167 |
168 | }
169 | }
170 |
171 | }
172 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/adapter/CityAdapter.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.adapter;
2 |
3 | import java.util.List;
4 |
5 | import android.content.Context;
6 | import android.view.View;
7 | import android.widget.TextView;
8 |
9 | import com.liucanwen.citylist.R;
10 | import com.liucanwen.citylist.widget.ContactItemInterface;
11 | import com.liucanwen.citylist.widget.ContactListAdapter;
12 |
13 | public class CityAdapter extends ContactListAdapter
14 | {
15 |
16 | public CityAdapter(Context _context, int _resource,
17 | List _items)
18 | {
19 | super(_context, _resource, _items);
20 | }
21 |
22 | public void populateDataForRow(View parentView, ContactItemInterface item,
23 | int position)
24 | {
25 | View infoView = parentView.findViewById(R.id.infoRowContainer);
26 | TextView nicknameView = (TextView) infoView
27 | .findViewById(R.id.cityName);
28 |
29 | nicknameView.setText(item.getDisplayInfo());
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/data/CityData.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/src/com/liucanwen/citylist/data/CityData.java
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/model/CityItem.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.model;
2 |
3 | import com.liucanwen.citylist.widget.ContactItemInterface;
4 |
5 | public class CityItem implements ContactItemInterface
6 | {
7 | private String nickName;
8 | private String fullName;
9 |
10 | public CityItem(String nickName, String fullName)
11 | {
12 | super();
13 | this.nickName = nickName;
14 | this.setFullName(fullName);
15 | }
16 |
17 | @Override
18 | public String getItemForIndex()
19 | {
20 | return fullName;
21 | }
22 |
23 | @Override
24 | public String getDisplayInfo()
25 | {
26 | return nickName;
27 | }
28 |
29 | public String getNickName()
30 | {
31 | return nickName;
32 | }
33 |
34 | public void setNickName(String nickName)
35 | {
36 | this.nickName = nickName;
37 | }
38 |
39 | public String getFullName()
40 | {
41 | return fullName;
42 | }
43 |
44 | public void setFullName(String fullName)
45 | {
46 | this.fullName = fullName;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/ContactItemComparator.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget;
2 |
3 | import java.util.Comparator;
4 |
5 | public class ContactItemComparator implements Comparator
6 | {
7 |
8 | @Override
9 | public int compare(ContactItemInterface lhs, ContactItemInterface rhs)
10 | {
11 | if (lhs.getItemForIndex() == null || rhs.getItemForIndex() == null)
12 | return -1;
13 |
14 | return (lhs.getItemForIndex().compareTo(rhs.getItemForIndex()));
15 |
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/ContactItemException.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget;
2 |
3 | public class ContactItemException extends Exception
4 | {
5 |
6 | public ContactItemException()
7 | {
8 | }
9 |
10 | public ContactItemException(String msg)
11 | {
12 | super(msg);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/ContactItemInterface.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/CityList/src/com/liucanwen/citylist/widget/ContactItemInterface.java
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/ContactListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 |
6 | import android.content.Context;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ArrayAdapter;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | import com.liucanwen.citylist.R;
15 |
16 | public class ContactListAdapter extends ArrayAdapter
17 | {
18 |
19 | private int resource; // store the resource layout id for 1 row
20 | private boolean inSearchMode = false;
21 |
22 | private ContactsSectionIndexer indexer = null;
23 |
24 | public ContactListAdapter(Context _context, int _resource,
25 | List _items)
26 | {
27 | super(_context, _resource, _items);
28 | resource = _resource;
29 |
30 | // need to sort the items array first, then pass it to the indexer
31 | Collections.sort(_items, new ContactItemComparator());
32 |
33 | setIndexer(new ContactsSectionIndexer(_items));
34 |
35 | }
36 |
37 | // get the section textview from row view
38 | // the section view will only be shown for the first item
39 | public TextView getSectionTextView(View rowView)
40 | {
41 | TextView sectionTextView = (TextView) rowView
42 | .findViewById(R.id.sectionTextView);
43 | return sectionTextView;
44 | }
45 |
46 | public void showSectionViewIfFirstItem(View rowView,
47 | ContactItemInterface item, int position)
48 | {
49 | TextView sectionTextView = getSectionTextView(rowView);
50 |
51 | // if in search mode then dun show the section header
52 | if (inSearchMode)
53 | {
54 | sectionTextView.setVisibility(View.GONE);
55 | } else
56 | {
57 | // if first item then show the header
58 |
59 | if (indexer.isFirstItemInSection(position))
60 | {
61 |
62 | String sectionTitle = indexer.getSectionTitle(item
63 | .getItemForIndex());
64 | sectionTextView.setText(sectionTitle);
65 | sectionTextView.setVisibility(View.VISIBLE);
66 |
67 | } else
68 | sectionTextView.setVisibility(View.GONE);
69 | }
70 | }
71 |
72 | // do all the data population for the row here
73 | // subclass overwrite this to draw more items
74 | public void populateDataForRow(View parentView, ContactItemInterface item,
75 | int position)
76 | {
77 | // default just draw the item only
78 | View infoView = parentView.findViewById(R.id.infoRowContainer);
79 | TextView nameView = (TextView) infoView.findViewById(R.id.cityName);
80 | nameView.setText(item.getItemForIndex());
81 | }
82 |
83 | // this should be override by subclass if necessary
84 | @Override
85 | public View getView(int position, View convertView, ViewGroup parent)
86 | {
87 | ViewGroup parentView;
88 |
89 | ContactItemInterface item = getItem(position);
90 |
91 | if (convertView == null)
92 | {
93 | parentView = new LinearLayout(getContext());
94 | String inflater = Context.LAYOUT_INFLATER_SERVICE;
95 | LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
96 | inflater);
97 | vi.inflate(resource, parentView, true);
98 | } else
99 | {
100 | parentView = (LinearLayout) convertView;
101 | }
102 |
103 | showSectionViewIfFirstItem(parentView, item, position);
104 |
105 | populateDataForRow(parentView, item, position);
106 |
107 | return parentView;
108 |
109 | }
110 |
111 | public boolean isInSearchMode()
112 | {
113 | return inSearchMode;
114 | }
115 |
116 | public void setInSearchMode(boolean inSearchMode)
117 | {
118 | this.inSearchMode = inSearchMode;
119 | }
120 |
121 | public ContactsSectionIndexer getIndexer()
122 | {
123 | return indexer;
124 | }
125 |
126 | public void setIndexer(ContactsSectionIndexer indexer)
127 | {
128 | this.indexer = indexer;
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/ContactListView.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget;
2 |
3 | import android.widget.ListView;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.util.AttributeSet;
8 | import android.view.GestureDetector;
9 | import android.view.MotionEvent;
10 | import android.widget.ListAdapter;
11 |
12 | public class ContactListView extends ListView
13 | {
14 |
15 | protected boolean mIsFastScrollEnabled = false;
16 | protected IndexScroller mScroller = null;
17 | protected GestureDetector mGestureDetector = null;
18 |
19 | // additional customization
20 | protected boolean inSearchMode = false; // whether is in search mode
21 | protected boolean autoHide = false; // alway show the scroller
22 |
23 | public ContactListView(Context context, AttributeSet attrs)
24 | {
25 | super(context, attrs);
26 | }
27 |
28 | public ContactListView(Context context, AttributeSet attrs, int defStyle)
29 | {
30 | super(context, attrs, defStyle);
31 | }
32 |
33 | public IndexScroller getScroller()
34 | {
35 | return mScroller;
36 | }
37 |
38 | @Override
39 | public boolean isFastScrollEnabled()
40 | {
41 | return mIsFastScrollEnabled;
42 | }
43 |
44 | // override this if necessary for custom scroller
45 | public void createScroller()
46 | {
47 | mScroller = new IndexScroller(getContext(), this);
48 | mScroller.setAutoHide(autoHide);
49 | mScroller.setShowIndexContainer(true);
50 |
51 | if (autoHide)
52 | mScroller.hide();
53 | else
54 | mScroller.show();
55 | }
56 |
57 | @Override
58 | public void setFastScrollEnabled(boolean enabled)
59 | {
60 | mIsFastScrollEnabled = enabled;
61 | if (mIsFastScrollEnabled)
62 | {
63 | if (mScroller == null)
64 | {
65 | createScroller();
66 | }
67 | } else
68 | {
69 | if (mScroller != null)
70 | {
71 | mScroller.hide();
72 | mScroller = null;
73 | }
74 | }
75 | }
76 |
77 | @Override
78 | public void draw(Canvas canvas)
79 | {
80 | super.draw(canvas);
81 |
82 | // Overlay index bar
83 | if (!inSearchMode) // dun draw the scroller if not in search mode
84 | {
85 | if (mScroller != null)
86 | mScroller.draw(canvas);
87 | }
88 |
89 | }
90 |
91 | @Override
92 | public boolean onTouchEvent(MotionEvent ev)
93 | {
94 | // Intercept ListView's touch event
95 | if (mScroller != null && mScroller.onTouchEvent(ev))
96 | return true;
97 |
98 | if (mGestureDetector == null)
99 | {
100 | mGestureDetector = new GestureDetector(getContext(),
101 | new GestureDetector.SimpleOnGestureListener()
102 | {
103 |
104 | @Override
105 | public boolean onFling(MotionEvent e1, MotionEvent e2,
106 | float velocityX, float velocityY)
107 | {
108 | // If fling happens, index bar shows
109 | mScroller.show();
110 | return super.onFling(e1, e2, velocityX, velocityY);
111 | }
112 |
113 | });
114 | }
115 | mGestureDetector.onTouchEvent(ev);
116 |
117 | return super.onTouchEvent(ev);
118 | }
119 |
120 | @Override
121 | public boolean onInterceptTouchEvent(MotionEvent ev)
122 | {
123 | return true;
124 | }
125 |
126 | @Override
127 | public void setAdapter(ListAdapter adapter)
128 | {
129 | super.setAdapter(adapter);
130 | if (mScroller != null)
131 | mScroller.setAdapter(adapter);
132 | }
133 |
134 | @Override
135 | protected void onSizeChanged(int w, int h, int oldw, int oldh)
136 | {
137 | super.onSizeChanged(w, h, oldw, oldh);
138 | if (mScroller != null)
139 | mScroller.onSizeChanged(w, h, oldw, oldh);
140 | }
141 |
142 | public boolean isInSearchMode()
143 | {
144 | return inSearchMode;
145 | }
146 |
147 | public void setInSearchMode(boolean inSearchMode)
148 | {
149 | this.inSearchMode = inSearchMode;
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/ContactListViewImpl.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.util.AttributeSet;
6 |
7 | public class ContactListViewImpl extends ContactListView
8 | {
9 |
10 | public ContactListViewImpl(Context context, AttributeSet attrs)
11 | {
12 | super(context, attrs);
13 | }
14 |
15 | public void createScroller()
16 | {
17 |
18 | mScroller = new IndexScroller(getContext(), this);
19 |
20 | mScroller.setAutoHide(autoHide);
21 |
22 | // style 1
23 | // mScroller.setShowIndexContainer(false);
24 | // mScroller.setIndexPaintColor(Color.argb(255, 49, 64, 91));
25 |
26 | // style 2
27 | mScroller.setShowIndexContainer(true);
28 | mScroller.setIndexPaintColor(Color.WHITE);
29 |
30 | if (autoHide)
31 | mScroller.hide();
32 | else
33 | mScroller.show();
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/ContactsSectionIndexer.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.widget.SectionIndexer;
9 |
10 | public class ContactsSectionIndexer implements SectionIndexer
11 | {
12 |
13 | private static String OTHER = "#";
14 | private static String[] mSections = { OTHER, "A", "B", "C", "D", "E", "F",
15 | "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
16 | "T", "U", "V", "W", "X", "Y", "Z" };
17 |
18 | private static int OTHER_INDEX = 0; // index of other in the mSections array
19 |
20 | private int[] mPositions; // store the list of starting position index for
21 | // each section
22 | // e.g. A start at index 0, B start at index 20,
23 | // C start at index 41 and so on
24 |
25 | private int mCount; // this is the count for total number of contacts
26 |
27 | // Assumption: the contacts array has been sorted
28 | public ContactsSectionIndexer(List contacts)
29 | {
30 | mCount = contacts.size();
31 |
32 | initPositions(contacts);
33 |
34 | }
35 |
36 | public String getSectionTitle(String indexableItem)
37 | {
38 | int sectionIndex = getSectionIndex(indexableItem);
39 | return mSections[sectionIndex];
40 | }
41 |
42 | // return which section this item belong to
43 | public int getSectionIndex(String indexableItem)
44 | {
45 | if (indexableItem == null)
46 | {
47 | return OTHER_INDEX;
48 | }
49 |
50 | indexableItem = indexableItem.trim();
51 | String firstLetter = OTHER;
52 |
53 | if (indexableItem.length() == 0)
54 | {
55 | return OTHER_INDEX;
56 | } else
57 | {
58 | // get the first letter
59 | firstLetter = String.valueOf(indexableItem.charAt(0)).toUpperCase();
60 | }
61 |
62 | int sectionCount = mSections.length;
63 | for (int i = 0; i < sectionCount; i++)
64 | {
65 | if (mSections[i].equals(firstLetter))
66 | {
67 | return i;
68 | }
69 | }
70 |
71 | return OTHER_INDEX;
72 |
73 | }
74 |
75 | // initialize the position index
76 | public void initPositions(List contacts)
77 | {
78 |
79 | int sectionCount = mSections.length;
80 | mPositions = new int[sectionCount];
81 |
82 | Arrays.fill(mPositions, -1); // initialize everything to -1
83 |
84 | // Assumption: list of items have already been sorted by the prefer
85 | // names
86 | int itemIndex = 0;
87 |
88 | for (ContactItemInterface contact : contacts)
89 | {
90 |
91 | String indexableItem = contact.getItemForIndex();
92 | int sectionIndex = getSectionIndex(indexableItem); // find out which
93 | // section this
94 | // item belong
95 | // to
96 |
97 | if (mPositions[sectionIndex] == -1) // if not set before, then do
98 | // this, otherwise just ignore
99 | mPositions[sectionIndex] = itemIndex;
100 |
101 | itemIndex++;
102 |
103 | }
104 |
105 | int lastPos = -1;
106 |
107 | // now loop through, for all the ones not found, set position to the one
108 | // before them
109 | // this is to make sure the array is sorted for binary search to work
110 | for (int i = 0; i < sectionCount; i++)
111 | {
112 | if (mPositions[i] == -1)
113 | mPositions[i] = lastPos;
114 |
115 | lastPos = mPositions[i];
116 |
117 | }
118 |
119 | }
120 |
121 | @Override
122 | public int getPositionForSection(int section)
123 | {
124 | if (section < 0 || section >= mSections.length)
125 | {
126 | return -1;
127 | }
128 |
129 | return mPositions[section];
130 | }
131 |
132 | @Override
133 | public int getSectionForPosition(int position)
134 | {
135 | if (position < 0 || position >= mCount)
136 | {
137 | return -1;
138 | }
139 |
140 | int index = Arrays.binarySearch(mPositions, position);
141 |
142 | /*
143 | * Consider this example: section positions are 0, 3, 5; the supplied
144 | * position is 4. The section corresponding to position 4 starts at
145 | * position 3, so the expected return value is 1. Binary search will not
146 | * find 4 in the array and thus will return -insertPosition-1, i.e. -3.
147 | * To get from that number to the expected value of 1 we need to negate
148 | * and subtract 2.
149 | */
150 | return index >= 0 ? index : -index - 2;
151 | }
152 |
153 | @Override
154 | public Object[] getSections()
155 | {
156 | return mSections;
157 | }
158 |
159 | // if first item in section, then return the section
160 | // otherwise return -1
161 | public boolean isFirstItemInSection(int position)
162 | { // check whether this item is the first item in section
163 | int section = Arrays.binarySearch(mPositions, position);
164 | return (section > -1);
165 |
166 | }
167 |
168 | }
169 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/IndexScroller.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.RectF;
8 | import android.os.Handler;
9 | import android.os.Message;
10 | import android.os.SystemClock;
11 | import android.util.Log;
12 | import android.view.MotionEvent;
13 | import android.widget.Adapter;
14 | import android.widget.ListView;
15 | import android.widget.SectionIndexer;
16 |
17 | // taken from https://github.com/woozzu/indexableListView IndexScroller
18 | // rewrite some sections to make it more customizable
19 | public class IndexScroller
20 | {
21 |
22 | /**
23 | * Add additional properties for customization
24 | *
25 | */
26 | // Hung - store the last touch down eventX and eventY so that we can detect
27 | // where user click on list view
28 | // indexscroller will override touch event of listview, so onclicklistener
29 | // will not work
30 | private float lastTouchDownEventX = -1;
31 | private float lastTouchDownEventY = -1;
32 |
33 | // whether to autohide the scroller
34 | // false will always show the index bar
35 | // true will hide the scrollbar at first, but slowly show it later
36 | private boolean autoHide = false;
37 |
38 | // minor optimizations
39 | private Paint indexbarContainerPaint = new Paint(); // paint for indexbar
40 | // container
41 | private Paint indexPaint = new Paint();
42 |
43 | private boolean showIndexContainer = false; // whether to show the outer
44 | // index container
45 | private int indexbarContainerBgColor = Color.BLACK;
46 | private int indexPaintColor = Color.WHITE; // color for section title
47 |
48 | // / end additional properties
49 |
50 | private float mIndexbarWidth;
51 | private float mIndexbarMargin;
52 | private float mPreviewPadding;
53 | private float mDensity;
54 | private float mScaledDensity;
55 | private float mAlphaRate;
56 | private int mState = STATE_HIDDEN;
57 | private int mListViewWidth;
58 | private int mListViewHeight;
59 | private int mCurrentSection = -1;
60 | private boolean mIsIndexing = false;
61 | private ListView mListView = null;
62 | private SectionIndexer mIndexer = null;
63 | private String[] mSections = null;
64 | private RectF mIndexbarRect;
65 |
66 | private static final int STATE_HIDDEN = 0;
67 | private static final int STATE_SHOWING = 1;
68 | private static final int STATE_SHOWN = 2;
69 | private static final int STATE_HIDING = 3;
70 |
71 | public IndexScroller(Context context, ListView lv)
72 | {
73 | mDensity = context.getResources().getDisplayMetrics().density;
74 | mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
75 | mListView = lv;
76 |
77 | setAdapter(mListView.getAdapter());
78 |
79 | mIndexbarWidth = 30 * mDensity;
80 | mIndexbarMargin = 0 * mDensity;
81 | mPreviewPadding = 5 * mDensity;
82 |
83 | // customization of paint colors
84 | // outer container
85 | indexbarContainerPaint.setAntiAlias(true);
86 |
87 | // letter in section
88 | indexPaint.setAntiAlias(true);
89 | indexPaint.setTextSize(12 * mScaledDensity);
90 | }
91 |
92 | public IndexScroller(Context context, ListView lv, SectionIndexer indexer)
93 | {
94 | this(context, lv);
95 |
96 | mIndexer = indexer;
97 |
98 | }
99 |
100 | // draw the outer rounded container
101 | public void drawIndexBarContainer(Canvas canvas)
102 | {
103 | indexbarContainerPaint.setColor(indexbarContainerBgColor);
104 | indexbarContainerPaint.setAlpha((int) (64 * mAlphaRate)); // opacity
105 | canvas.drawRoundRect(mIndexbarRect, 5 * mDensity, 5 * mDensity,
106 | indexbarContainerPaint);
107 | }
108 |
109 | public void drawSections(Canvas canvas)
110 | {
111 | indexPaint.setColor(indexPaintColor);
112 | indexPaint.setAlpha((int) (255 * mAlphaRate));
113 |
114 | float sectionHeight = (mIndexbarRect.height() - 2 * mIndexbarMargin)
115 | / mSections.length;
116 | float paddingTop = (sectionHeight - (indexPaint.descent() - indexPaint
117 | .ascent())) / 2;
118 |
119 | // draw the section letters
120 | for (int i = 0; i < mSections.length; i++)
121 | {
122 | float paddingLeft = (mIndexbarWidth - indexPaint
123 | .measureText(mSections[i])) / 2;
124 | canvas.drawText(mSections[i], mIndexbarRect.left + paddingLeft,
125 | mIndexbarRect.top + mIndexbarMargin + sectionHeight * i
126 | + paddingTop - indexPaint.ascent(), indexPaint);
127 | }
128 | }
129 |
130 | public void drawCurrentSection(Canvas canvas)
131 | {
132 | if (mCurrentSection >= 0)
133 | {
134 |
135 | // Log.i("IndexScroller", "current section: " + mCurrentSection);
136 |
137 | // Preview is shown when mCurrentSection is set
138 | // mCurrentSection is the letter that is being pressed
139 | // this will draw the big preview text on top of the listview
140 | Paint previewPaint = new Paint();
141 | previewPaint.setColor(Color.BLACK);
142 | previewPaint.setAlpha(96);
143 | previewPaint.setAntiAlias(true);
144 | previewPaint.setShadowLayer(3, 0, 0, Color.argb(64, 0, 0, 0));
145 |
146 | Paint previewTextPaint = new Paint();
147 | previewTextPaint.setColor(Color.WHITE);
148 | previewTextPaint.setAntiAlias(true);
149 | previewTextPaint.setTextSize(50 * mScaledDensity);
150 |
151 | float previewTextWidth = previewTextPaint
152 | .measureText(mSections[mCurrentSection]);
153 | float previewSize = 2 * mPreviewPadding
154 | + previewTextPaint.descent() - previewTextPaint.ascent();
155 | RectF previewRect = new RectF((mListViewWidth - previewSize) / 2,
156 | (mListViewHeight - previewSize) / 2,
157 | (mListViewWidth - previewSize) / 2 + previewSize,
158 | (mListViewHeight - previewSize) / 2 + previewSize);
159 |
160 | canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity,
161 | previewPaint);
162 | canvas.drawText(mSections[mCurrentSection], previewRect.left
163 | + (previewSize - previewTextWidth) / 2 - 1, previewRect.top
164 | + mPreviewPadding - previewTextPaint.ascent() + 1,
165 | previewTextPaint);
166 | }
167 | }
168 |
169 | public void draw(Canvas canvas)
170 | {
171 | if (mState == STATE_HIDDEN)
172 | return;
173 |
174 | if (showIndexContainer)
175 | drawIndexBarContainer(canvas);
176 |
177 | if (mSections != null && mSections.length > 0)
178 | {
179 |
180 | drawCurrentSection(canvas);
181 | drawSections(canvas);
182 | }
183 | }
184 |
185 | public boolean onTouchEvent(MotionEvent ev)
186 | {
187 | switch (ev.getAction())
188 | {
189 | case MotionEvent.ACTION_DOWN:
190 | lastTouchDownEventX = ev.getX(); // Hung capture the event for later
191 | // use in listview item click
192 | lastTouchDownEventY = ev.getY();
193 |
194 | // If down event occurs inside index bar region, start indexing
195 | if (mState != STATE_HIDDEN && contains(ev.getX(), ev.getY()))
196 | {
197 | setState(STATE_SHOWN);
198 |
199 | // It demonstrates that the motion event started from index bar
200 | mIsIndexing = true;
201 | // Determine which section the point is in, and move the list to
202 | // that section
203 | mCurrentSection = getSectionByPoint(ev.getY());
204 | mListView.setSelection(mIndexer
205 | .getPositionForSection(mCurrentSection));
206 | return true;
207 | }
208 | break;
209 | case MotionEvent.ACTION_MOVE:
210 | if (mIsIndexing)
211 | {
212 | // If this event moves inside index bar
213 | if (contains(ev.getX(), ev.getY()))
214 | {
215 | // Determine which section the point is in, and move the
216 | // list to that section
217 | mCurrentSection = getSectionByPoint(ev.getY());
218 | mListView.setSelection(mIndexer
219 | .getPositionForSection(mCurrentSection));
220 | }
221 | return true;
222 | }
223 | break;
224 | case MotionEvent.ACTION_UP:
225 | if (mIsIndexing)
226 | {
227 | mIsIndexing = false;
228 | mCurrentSection = -1;
229 | }
230 | // only hide if state is auto hiding
231 | if (autoHide)
232 | {
233 | if (mState == STATE_SHOWN)
234 | setState(STATE_HIDING);
235 | }
236 | break;
237 | }
238 | return false;
239 | }
240 |
241 | public void onSizeChanged(int w, int h, int oldw, int oldh)
242 | {
243 | mListViewWidth = w;
244 | mListViewHeight = h;
245 | mIndexbarRect = new RectF(w - mIndexbarMargin - mIndexbarWidth,
246 | mIndexbarMargin, w - mIndexbarMargin, h - mIndexbarMargin);
247 | }
248 |
249 | public void show()
250 | {
251 | if (mState == STATE_HIDDEN)
252 | setState(STATE_SHOWING);
253 | else if (mState == STATE_HIDING)
254 | setState(STATE_HIDING);
255 | }
256 |
257 | public void hide()
258 | {
259 | if (mState == STATE_SHOWN)
260 | setState(STATE_HIDING);
261 | }
262 |
263 | public void setAdapter(Adapter adapter)
264 | {
265 | if (adapter instanceof SectionIndexer)
266 | {
267 | mIndexer = (SectionIndexer) adapter;
268 | mSections = (String[]) mIndexer.getSections();
269 | } else if (adapter instanceof ContactListAdapter)
270 | {
271 | ContactListAdapter c = (ContactListAdapter) adapter;
272 | mIndexer = c.getIndexer();
273 | mSections = (String[]) mIndexer.getSections();
274 | }
275 | }
276 |
277 | private void setState(int state)
278 | {
279 | if (state < STATE_HIDDEN || state > STATE_HIDING)
280 | return;
281 |
282 | mState = state;
283 | switch (mState)
284 | {
285 | case STATE_HIDDEN:
286 | // Cancel any fade effect
287 | mHandler.removeMessages(0);
288 | break;
289 | case STATE_SHOWING:
290 | // Start to fade in
291 | mAlphaRate = 0;
292 | fade(0);
293 | break;
294 | case STATE_SHOWN:
295 | // Cancel any fade effect
296 | mHandler.removeMessages(0);
297 | break;
298 | case STATE_HIDING:
299 | // Start to fade out after three seconds
300 | mAlphaRate = 1;
301 | fade(3000);
302 | break;
303 | }
304 | }
305 |
306 | private boolean contains(float x, float y)
307 | {
308 | // Determine if the point is in index bar region, which includes the
309 | // right margin of the bar
310 | return (x >= mIndexbarRect.left && y >= mIndexbarRect.top && y <= mIndexbarRect.top
311 | + mIndexbarRect.height());
312 | }
313 |
314 | private int getSectionByPoint(float y)
315 | {
316 | if (mSections == null || mSections.length == 0)
317 | return 0;
318 | if (y < mIndexbarRect.top + mIndexbarMargin)
319 | return 0;
320 | if (y >= mIndexbarRect.top + mIndexbarRect.height() - mIndexbarMargin)
321 | return mSections.length - 1;
322 | return (int) ((y - mIndexbarRect.top - mIndexbarMargin) / ((mIndexbarRect
323 | .height() - 2 * mIndexbarMargin) / mSections.length));
324 | }
325 |
326 | private void fade(long delay)
327 | {
328 | mHandler.removeMessages(0);
329 | mHandler.sendEmptyMessageAtTime(0, SystemClock.uptimeMillis() + delay);
330 | }
331 |
332 | private Handler mHandler = new Handler()
333 | {
334 |
335 | @Override
336 | public void handleMessage(Message msg)
337 | {
338 | super.handleMessage(msg);
339 |
340 | switch (mState)
341 | {
342 | case STATE_SHOWING:
343 | // Fade in effect
344 | mAlphaRate += (1 - mAlphaRate) * 0.2;
345 | if (mAlphaRate > 0.9)
346 | {
347 | mAlphaRate = 1;
348 | setState(STATE_SHOWN);
349 | }
350 |
351 | mListView.invalidate();
352 | fade(10);
353 | break;
354 | case STATE_SHOWN:
355 | // If no action, hide automatically
356 | // Hung - comment out this to disable hiding
357 | if (autoHide)
358 | {
359 | setState(STATE_HIDING);
360 | }
361 | break;
362 | case STATE_HIDING:
363 | // Fade out effect
364 | mAlphaRate -= mAlphaRate * 0.2;
365 | if (mAlphaRate < 0.1)
366 | {
367 | mAlphaRate = 0;
368 | setState(STATE_HIDDEN);
369 | }
370 |
371 | mListView.invalidate();
372 | fade(10);
373 | break;
374 | }
375 | }
376 |
377 | };
378 |
379 | public float getLastTouchDownEventX()
380 | {
381 | return lastTouchDownEventX;
382 | }
383 |
384 | public void setLastTouchDownEventX(float lastTouchDownEventX)
385 | {
386 | this.lastTouchDownEventX = lastTouchDownEventX;
387 | }
388 |
389 | public float getLastTouchDownEventY()
390 | {
391 | return lastTouchDownEventY;
392 | }
393 |
394 | public void setLastTouchDownEventY(float lastTouchDownEventY)
395 | {
396 | this.lastTouchDownEventY = lastTouchDownEventY;
397 | }
398 |
399 | public boolean isAutoHide()
400 | {
401 | return autoHide;
402 | }
403 |
404 | public void setAutoHide(boolean autoHide)
405 | {
406 | this.autoHide = autoHide;
407 | }
408 |
409 | public boolean isShowIndexContainer()
410 | {
411 | return showIndexContainer;
412 | }
413 |
414 | public void setShowIndexContainer(boolean showIndexContainer)
415 | {
416 | this.showIndexContainer = showIndexContainer;
417 | }
418 |
419 | public int getIndexbarContainerBgColor()
420 | {
421 | return indexbarContainerBgColor;
422 | }
423 |
424 | public void setIndexbarContainerBgColor(int indexbarContainerBgColor)
425 | {
426 | this.indexbarContainerBgColor = indexbarContainerBgColor;
427 | }
428 |
429 | public int getIndexPaintColor()
430 | {
431 | return indexPaintColor;
432 | }
433 |
434 | public void setIndexPaintColor(int indexPaintColor)
435 | {
436 | this.indexPaintColor = indexPaintColor;
437 | }
438 |
439 | }
440 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/pinyin/HanziToPinyin3.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.liucanwen.citylist.widget.pinyin;
18 |
19 | import java.text.Collator;
20 | import java.util.ArrayList;
21 | import java.util.Locale;
22 |
23 | import android.text.TextUtils;
24 | import android.util.Log;
25 |
26 | /**
27 | * An object to convert Chinese character to its corresponding pinyin string. For characters with
28 | * multiple possible pinyin string, only one is selected according to collator. Polyphone is not
29 | * supported in this implementation. This class is implemented to achieve the best runtime
30 | * performance and minimum runtime resources with tolerable sacrifice of accuracy. This
31 | * implementation highly depends on zh_CN ICU collation data and must be always synchronized with
32 | * ICU.
33 | *
34 | * Currently this file is aligned to zh.txt in ICU 4.6
35 | * 来自android4.2源码
36 | */
37 | public class HanziToPinyin3 {
38 | private static final String TAG = "HanziToPinyin";
39 |
40 | // Turn on this flag when we want to check internal data structure.
41 | private static final boolean DEBUG = false;
42 |
43 | /**
44 | * Unihans array.
45 | *
46 | * Each unihans is the first one within same pinyin when collator is zh_CN.
47 | */
48 | public static final char[] UNIHANS = {
49 | '\u963f', '\u54ce', '\u5b89', '\u80ae', '\u51f9', '\u516b',
50 | '\u6300', '\u6273', '\u90a6', '\u52f9', '\u9642', '\u5954',
51 | '\u4f3b', '\u5c44', '\u8fb9', '\u706c', '\u618b', '\u6c43',
52 | '\u51ab', '\u7676', '\u5cec', '\u5693', '\u5072', '\u53c2',
53 | '\u4ed3', '\u64a1', '\u518a', '\u5d7e', '\u66fd', '\u66fe',
54 | '\u5c64', '\u53c9', '\u8286', '\u8fbf', '\u4f25', '\u6284',
55 | '\u8f66', '\u62bb', '\u6c88', '\u6c89', '\u9637', '\u5403',
56 | '\u5145', '\u62bd', '\u51fa', '\u6b3b', '\u63e3', '\u5ddb',
57 | '\u5205', '\u5439', '\u65fe', '\u9034', '\u5472', '\u5306',
58 | '\u51d1', '\u7c97', '\u6c46', '\u5d14', '\u90a8', '\u6413',
59 | '\u5491', '\u5446', '\u4e39', '\u5f53', '\u5200', '\u561a',
60 | '\u6265', '\u706f', '\u6c10', '\u55f2', '\u7538', '\u5201',
61 | '\u7239', '\u4e01', '\u4e1f', '\u4e1c', '\u543a', '\u53be',
62 | '\u8011', '\u8968', '\u5428', '\u591a', '\u59b8', '\u8bf6',
63 | '\u5940', '\u97a5', '\u513f', '\u53d1', '\u5e06', '\u531a',
64 | '\u98de', '\u5206', '\u4e30', '\u8985', '\u4ecf', '\u7d11',
65 | '\u4f15', '\u65ee', '\u4f85', '\u7518', '\u5188', '\u768b',
66 | '\u6208', '\u7ed9', '\u6839', '\u522f', '\u5de5', '\u52fe',
67 | '\u4f30', '\u74dc', '\u4e56', '\u5173', '\u5149', '\u5f52',
68 | '\u4e28', '\u5459', '\u54c8', '\u548d', '\u4f44', '\u592f',
69 | '\u8320', '\u8bc3', '\u9ed2', '\u62eb', '\u4ea8', '\u5677',
70 | '\u53ff', '\u9f41', '\u4e6f', '\u82b1', '\u6000', '\u72bf',
71 | '\u5ddf', '\u7070', '\u660f', '\u5419', '\u4e0c', '\u52a0',
72 | '\u620b', '\u6c5f', '\u827d', '\u9636', '\u5dfe', '\u5755',
73 | '\u5182', '\u4e29', '\u51e5', '\u59e2', '\u5658', '\u519b',
74 | '\u5494', '\u5f00', '\u520a', '\u5ffc', '\u5c3b', '\u533c',
75 | '\u808e', '\u52a5', '\u7a7a', '\u62a0', '\u625d', '\u5938',
76 | '\u84af', '\u5bbd', '\u5321', '\u4e8f', '\u5764', '\u6269',
77 | '\u5783', '\u6765', '\u5170', '\u5577', '\u635e', '\u808b',
78 | '\u52d2', '\u5d1a', '\u5215', '\u4fe9', '\u5941', '\u826f',
79 | '\u64a9', '\u5217', '\u62ce', '\u5222', '\u6e9c', '\u56d6',
80 | '\u9f99', '\u779c', '\u565c', '\u5a08', '\u7567', '\u62a1',
81 | '\u7f57', '\u5463', '\u5988', '\u57cb', '\u5ada', '\u7264',
82 | '\u732b', '\u4e48', '\u5445', '\u95e8', '\u753f', '\u54aa',
83 | '\u5b80', '\u55b5', '\u4e5c', '\u6c11', '\u540d', '\u8c2c',
84 | '\u6478', '\u54de', '\u6bea', '\u55ef', '\u62cf', '\u8149',
85 | '\u56e1', '\u56d4', '\u5b6c', '\u7592', '\u5a1e', '\u6041',
86 | '\u80fd', '\u59ae', '\u62c8', '\u5b22', '\u9e1f', '\u634f',
87 | '\u56dc', '\u5b81', '\u599e', '\u519c', '\u7fba', '\u5974',
88 | '\u597b', '\u759f', '\u9ec1', '\u90cd', '\u5594', '\u8bb4',
89 | '\u5991', '\u62cd', '\u7705', '\u4e53', '\u629b', '\u5478',
90 | '\u55b7', '\u5309', '\u4e15', '\u56e8', '\u527d', '\u6c15',
91 | '\u59d8', '\u4e52', '\u948b', '\u5256', '\u4ec6', '\u4e03',
92 | '\u6390', '\u5343', '\u545b', '\u6084', '\u767f', '\u4eb2',
93 | '\u72c5', '\u828e', '\u4e18', '\u533a', '\u5cd1', '\u7f3a',
94 | '\u590b', '\u5465', '\u7a63', '\u5a06', '\u60f9', '\u4eba',
95 | '\u6254', '\u65e5', '\u8338', '\u53b9', '\u909a', '\u633c',
96 | '\u5827', '\u5a51', '\u77a4', '\u637c', '\u4ee8', '\u6be2',
97 | '\u4e09', '\u6852', '\u63bb', '\u95aa', '\u68ee', '\u50e7',
98 | '\u6740', '\u7b5b', '\u5c71', '\u4f24', '\u5f30', '\u5962',
99 | '\u7533', '\u8398', '\u6552', '\u5347', '\u5c38', '\u53ce',
100 | '\u4e66', '\u5237', '\u8870', '\u95e9', '\u53cc', '\u8c01',
101 | '\u542e', '\u8bf4', '\u53b6', '\u5fea', '\u635c', '\u82cf',
102 | '\u72fb', '\u590a', '\u5b59', '\u5506', '\u4ed6', '\u56fc',
103 | '\u574d', '\u6c64', '\u5932', '\u5fd1', '\u71a5', '\u5254',
104 | '\u5929', '\u65eb', '\u5e16', '\u5385', '\u56f2', '\u5077',
105 | '\u51f8', '\u6e4d', '\u63a8', '\u541e', '\u4e47', '\u7a75',
106 | '\u6b6a', '\u5f2f', '\u5c23', '\u5371', '\u6637', '\u7fc1',
107 | '\u631d', '\u4e4c', '\u5915', '\u8672', '\u4eda', '\u4e61',
108 | '\u7071', '\u4e9b', '\u5fc3', '\u661f', '\u51f6', '\u4f11',
109 | '\u5401', '\u5405', '\u524a', '\u5743', '\u4e2b', '\u6079',
110 | '\u592e', '\u5e7a', '\u503b', '\u4e00', '\u56d9', '\u5e94',
111 | '\u54df', '\u4f63', '\u4f18', '\u625c', '\u56e6', '\u66f0',
112 | '\u6655', '\u7b60', '\u7b7c', '\u5e00', '\u707d', '\u5142',
113 | '\u5328', '\u50ae', '\u5219', '\u8d3c', '\u600e', '\u5897',
114 | '\u624e', '\u635a', '\u6cbe', '\u5f20', '\u957f', '\u9577',
115 | '\u4f4b', '\u8707', '\u8d1e', '\u4e89', '\u4e4b', '\u5cd9',
116 | '\u5ea2', '\u4e2d', '\u5dde', '\u6731', '\u6293', '\u62fd',
117 | '\u4e13', '\u5986', '\u96b9', '\u5b92', '\u5353', '\u4e72',
118 | '\u5b97', '\u90b9', '\u79df', '\u94bb', '\u539c', '\u5c0a',
119 | '\u6628', '\u5159', '\u9fc3', '\u9fc4', };
120 |
121 | /**
122 | * Pinyin array.
123 | *
124 | * Each pinyin is corresponding to unihans of same
125 | * offset in the unihans array.
126 | */
127 | public static final byte[][] PINYINS = {
128 | { 65, 0, 0, 0, 0, 0}, { 65, 73, 0, 0, 0, 0},
129 | { 65, 78, 0, 0, 0, 0}, { 65, 78, 71, 0, 0, 0},
130 | { 65, 79, 0, 0, 0, 0}, { 66, 65, 0, 0, 0, 0},
131 | { 66, 65, 73, 0, 0, 0}, { 66, 65, 78, 0, 0, 0},
132 | { 66, 65, 78, 71, 0, 0}, { 66, 65, 79, 0, 0, 0},
133 | { 66, 69, 73, 0, 0, 0}, { 66, 69, 78, 0, 0, 0},
134 | { 66, 69, 78, 71, 0, 0}, { 66, 73, 0, 0, 0, 0},
135 | { 66, 73, 65, 78, 0, 0}, { 66, 73, 65, 79, 0, 0},
136 | { 66, 73, 69, 0, 0, 0}, { 66, 73, 78, 0, 0, 0},
137 | { 66, 73, 78, 71, 0, 0}, { 66, 79, 0, 0, 0, 0},
138 | { 66, 85, 0, 0, 0, 0}, { 67, 65, 0, 0, 0, 0},
139 | { 67, 65, 73, 0, 0, 0}, { 67, 65, 78, 0, 0, 0},
140 | { 67, 65, 78, 71, 0, 0}, { 67, 65, 79, 0, 0, 0},
141 | { 67, 69, 0, 0, 0, 0}, { 67, 69, 78, 0, 0, 0},
142 | { 67, 69, 78, 71, 0, 0}, { 90, 69, 78, 71, 0, 0},
143 | { 67, 69, 78, 71, 0, 0}, { 67, 72, 65, 0, 0, 0},
144 | { 67, 72, 65, 73, 0, 0}, { 67, 72, 65, 78, 0, 0},
145 | { 67, 72, 65, 78, 71, 0}, { 67, 72, 65, 79, 0, 0},
146 | { 67, 72, 69, 0, 0, 0}, { 67, 72, 69, 78, 0, 0},
147 | { 83, 72, 69, 78, 0, 0}, { 67, 72, 69, 78, 0, 0},
148 | { 67, 72, 69, 78, 71, 0}, { 67, 72, 73, 0, 0, 0},
149 | { 67, 72, 79, 78, 71, 0}, { 67, 72, 79, 85, 0, 0},
150 | { 67, 72, 85, 0, 0, 0}, { 67, 72, 85, 65, 0, 0},
151 | { 67, 72, 85, 65, 73, 0}, { 67, 72, 85, 65, 78, 0},
152 | { 67, 72, 85, 65, 78, 71}, { 67, 72, 85, 73, 0, 0},
153 | { 67, 72, 85, 78, 0, 0}, { 67, 72, 85, 79, 0, 0},
154 | { 67, 73, 0, 0, 0, 0}, { 67, 79, 78, 71, 0, 0},
155 | { 67, 79, 85, 0, 0, 0}, { 67, 85, 0, 0, 0, 0},
156 | { 67, 85, 65, 78, 0, 0}, { 67, 85, 73, 0, 0, 0},
157 | { 67, 85, 78, 0, 0, 0}, { 67, 85, 79, 0, 0, 0},
158 | { 68, 65, 0, 0, 0, 0}, { 68, 65, 73, 0, 0, 0},
159 | { 68, 65, 78, 0, 0, 0}, { 68, 65, 78, 71, 0, 0},
160 | { 68, 65, 79, 0, 0, 0}, { 68, 69, 0, 0, 0, 0},
161 | { 68, 69, 78, 0, 0, 0}, { 68, 69, 78, 71, 0, 0},
162 | { 68, 73, 0, 0, 0, 0}, { 68, 73, 65, 0, 0, 0},
163 | { 68, 73, 65, 78, 0, 0}, { 68, 73, 65, 79, 0, 0},
164 | { 68, 73, 69, 0, 0, 0}, { 68, 73, 78, 71, 0, 0},
165 | { 68, 73, 85, 0, 0, 0}, { 68, 79, 78, 71, 0, 0},
166 | { 68, 79, 85, 0, 0, 0}, { 68, 85, 0, 0, 0, 0},
167 | { 68, 85, 65, 78, 0, 0}, { 68, 85, 73, 0, 0, 0},
168 | { 68, 85, 78, 0, 0, 0}, { 68, 85, 79, 0, 0, 0},
169 | { 69, 0, 0, 0, 0, 0}, { 69, 73, 0, 0, 0, 0},
170 | { 69, 78, 0, 0, 0, 0}, { 69, 78, 71, 0, 0, 0},
171 | { 69, 82, 0, 0, 0, 0}, { 70, 65, 0, 0, 0, 0},
172 | { 70, 65, 78, 0, 0, 0}, { 70, 65, 78, 71, 0, 0},
173 | { 70, 69, 73, 0, 0, 0}, { 70, 69, 78, 0, 0, 0},
174 | { 70, 69, 78, 71, 0, 0}, { 70, 73, 65, 79, 0, 0},
175 | { 70, 79, 0, 0, 0, 0}, { 70, 79, 85, 0, 0, 0},
176 | { 70, 85, 0, 0, 0, 0}, { 71, 65, 0, 0, 0, 0},
177 | { 71, 65, 73, 0, 0, 0}, { 71, 65, 78, 0, 0, 0},
178 | { 71, 65, 78, 71, 0, 0}, { 71, 65, 79, 0, 0, 0},
179 | { 71, 69, 0, 0, 0, 0}, { 71, 69, 73, 0, 0, 0},
180 | { 71, 69, 78, 0, 0, 0}, { 71, 69, 78, 71, 0, 0},
181 | { 71, 79, 78, 71, 0, 0}, { 71, 79, 85, 0, 0, 0},
182 | { 71, 85, 0, 0, 0, 0}, { 71, 85, 65, 0, 0, 0},
183 | { 71, 85, 65, 73, 0, 0}, { 71, 85, 65, 78, 0, 0},
184 | { 71, 85, 65, 78, 71, 0}, { 71, 85, 73, 0, 0, 0},
185 | { 71, 85, 78, 0, 0, 0}, { 71, 85, 79, 0, 0, 0},
186 | { 72, 65, 0, 0, 0, 0}, { 72, 65, 73, 0, 0, 0},
187 | { 72, 65, 78, 0, 0, 0}, { 72, 65, 78, 71, 0, 0},
188 | { 72, 65, 79, 0, 0, 0}, { 72, 69, 0, 0, 0, 0},
189 | { 72, 69, 73, 0, 0, 0}, { 72, 69, 78, 0, 0, 0},
190 | { 72, 69, 78, 71, 0, 0}, { 72, 77, 0, 0, 0, 0},
191 | { 72, 79, 78, 71, 0, 0}, { 72, 79, 85, 0, 0, 0},
192 | { 72, 85, 0, 0, 0, 0}, { 72, 85, 65, 0, 0, 0},
193 | { 72, 85, 65, 73, 0, 0}, { 72, 85, 65, 78, 0, 0},
194 | { 72, 85, 65, 78, 71, 0}, { 72, 85, 73, 0, 0, 0},
195 | { 72, 85, 78, 0, 0, 0}, { 72, 85, 79, 0, 0, 0},
196 | { 74, 73, 0, 0, 0, 0}, { 74, 73, 65, 0, 0, 0},
197 | { 74, 73, 65, 78, 0, 0}, { 74, 73, 65, 78, 71, 0},
198 | { 74, 73, 65, 79, 0, 0}, { 74, 73, 69, 0, 0, 0},
199 | { 74, 73, 78, 0, 0, 0}, { 74, 73, 78, 71, 0, 0},
200 | { 74, 73, 79, 78, 71, 0}, { 74, 73, 85, 0, 0, 0},
201 | { 74, 85, 0, 0, 0, 0}, { 74, 85, 65, 78, 0, 0},
202 | { 74, 85, 69, 0, 0, 0}, { 74, 85, 78, 0, 0, 0},
203 | { 75, 65, 0, 0, 0, 0}, { 75, 65, 73, 0, 0, 0},
204 | { 75, 65, 78, 0, 0, 0}, { 75, 65, 78, 71, 0, 0},
205 | { 75, 65, 79, 0, 0, 0}, { 75, 69, 0, 0, 0, 0},
206 | { 75, 69, 78, 0, 0, 0}, { 75, 69, 78, 71, 0, 0},
207 | { 75, 79, 78, 71, 0, 0}, { 75, 79, 85, 0, 0, 0},
208 | { 75, 85, 0, 0, 0, 0}, { 75, 85, 65, 0, 0, 0},
209 | { 75, 85, 65, 73, 0, 0}, { 75, 85, 65, 78, 0, 0},
210 | { 75, 85, 65, 78, 71, 0}, { 75, 85, 73, 0, 0, 0},
211 | { 75, 85, 78, 0, 0, 0}, { 75, 85, 79, 0, 0, 0},
212 | { 76, 65, 0, 0, 0, 0}, { 76, 65, 73, 0, 0, 0},
213 | { 76, 65, 78, 0, 0, 0}, { 76, 65, 78, 71, 0, 0},
214 | { 76, 65, 79, 0, 0, 0}, { 76, 69, 0, 0, 0, 0},
215 | { 76, 69, 73, 0, 0, 0}, { 76, 69, 78, 71, 0, 0},
216 | { 76, 73, 0, 0, 0, 0}, { 76, 73, 65, 0, 0, 0},
217 | { 76, 73, 65, 78, 0, 0}, { 76, 73, 65, 78, 71, 0},
218 | { 76, 73, 65, 79, 0, 0}, { 76, 73, 69, 0, 0, 0},
219 | { 76, 73, 78, 0, 0, 0}, { 76, 73, 78, 71, 0, 0},
220 | { 76, 73, 85, 0, 0, 0}, { 76, 79, 0, 0, 0, 0},
221 | { 76, 79, 78, 71, 0, 0}, { 76, 79, 85, 0, 0, 0},
222 | { 76, 85, 0, 0, 0, 0}, { 76, 85, 65, 78, 0, 0},
223 | { 76, 85, 69, 0, 0, 0}, { 76, 85, 78, 0, 0, 0},
224 | { 76, 85, 79, 0, 0, 0}, { 77, 0, 0, 0, 0, 0},
225 | { 77, 65, 0, 0, 0, 0}, { 77, 65, 73, 0, 0, 0},
226 | { 77, 65, 78, 0, 0, 0}, { 77, 65, 78, 71, 0, 0},
227 | { 77, 65, 79, 0, 0, 0}, { 77, 69, 0, 0, 0, 0},
228 | { 77, 69, 73, 0, 0, 0}, { 77, 69, 78, 0, 0, 0},
229 | { 77, 69, 78, 71, 0, 0}, { 77, 73, 0, 0, 0, 0},
230 | { 77, 73, 65, 78, 0, 0}, { 77, 73, 65, 79, 0, 0},
231 | { 77, 73, 69, 0, 0, 0}, { 77, 73, 78, 0, 0, 0},
232 | { 77, 73, 78, 71, 0, 0}, { 77, 73, 85, 0, 0, 0},
233 | { 77, 79, 0, 0, 0, 0}, { 77, 79, 85, 0, 0, 0},
234 | { 77, 85, 0, 0, 0, 0}, { 78, 0, 0, 0, 0, 0},
235 | { 78, 65, 0, 0, 0, 0}, { 78, 65, 73, 0, 0, 0},
236 | { 78, 65, 78, 0, 0, 0}, { 78, 65, 78, 71, 0, 0},
237 | { 78, 65, 79, 0, 0, 0}, { 78, 69, 0, 0, 0, 0},
238 | { 78, 69, 73, 0, 0, 0}, { 78, 69, 78, 0, 0, 0},
239 | { 78, 69, 78, 71, 0, 0}, { 78, 73, 0, 0, 0, 0},
240 | { 78, 73, 65, 78, 0, 0}, { 78, 73, 65, 78, 71, 0},
241 | { 78, 73, 65, 79, 0, 0}, { 78, 73, 69, 0, 0, 0},
242 | { 78, 73, 78, 0, 0, 0}, { 78, 73, 78, 71, 0, 0},
243 | { 78, 73, 85, 0, 0, 0}, { 78, 79, 78, 71, 0, 0},
244 | { 78, 79, 85, 0, 0, 0}, { 78, 85, 0, 0, 0, 0},
245 | { 78, 85, 65, 78, 0, 0}, { 78, 85, 69, 0, 0, 0},
246 | { 78, 85, 78, 0, 0, 0}, { 78, 85, 79, 0, 0, 0},
247 | { 79, 0, 0, 0, 0, 0}, { 79, 85, 0, 0, 0, 0},
248 | { 80, 65, 0, 0, 0, 0}, { 80, 65, 73, 0, 0, 0},
249 | { 80, 65, 78, 0, 0, 0}, { 80, 65, 78, 71, 0, 0},
250 | { 80, 65, 79, 0, 0, 0}, { 80, 69, 73, 0, 0, 0},
251 | { 80, 69, 78, 0, 0, 0}, { 80, 69, 78, 71, 0, 0},
252 | { 80, 73, 0, 0, 0, 0}, { 80, 73, 65, 78, 0, 0},
253 | { 80, 73, 65, 79, 0, 0}, { 80, 73, 69, 0, 0, 0},
254 | { 80, 73, 78, 0, 0, 0}, { 80, 73, 78, 71, 0, 0},
255 | { 80, 79, 0, 0, 0, 0}, { 80, 79, 85, 0, 0, 0},
256 | { 80, 85, 0, 0, 0, 0}, { 81, 73, 0, 0, 0, 0},
257 | { 81, 73, 65, 0, 0, 0}, { 81, 73, 65, 78, 0, 0},
258 | { 81, 73, 65, 78, 71, 0}, { 81, 73, 65, 79, 0, 0},
259 | { 81, 73, 69, 0, 0, 0}, { 81, 73, 78, 0, 0, 0},
260 | { 81, 73, 78, 71, 0, 0}, { 81, 73, 79, 78, 71, 0},
261 | { 81, 73, 85, 0, 0, 0}, { 81, 85, 0, 0, 0, 0},
262 | { 81, 85, 65, 78, 0, 0}, { 81, 85, 69, 0, 0, 0},
263 | { 81, 85, 78, 0, 0, 0}, { 82, 65, 78, 0, 0, 0},
264 | { 82, 65, 78, 71, 0, 0}, { 82, 65, 79, 0, 0, 0},
265 | { 82, 69, 0, 0, 0, 0}, { 82, 69, 78, 0, 0, 0},
266 | { 82, 69, 78, 71, 0, 0}, { 82, 73, 0, 0, 0, 0},
267 | { 82, 79, 78, 71, 0, 0}, { 82, 79, 85, 0, 0, 0},
268 | { 82, 85, 0, 0, 0, 0}, { 82, 85, 65, 0, 0, 0},
269 | { 82, 85, 65, 78, 0, 0}, { 82, 85, 73, 0, 0, 0},
270 | { 82, 85, 78, 0, 0, 0}, { 82, 85, 79, 0, 0, 0},
271 | { 83, 65, 0, 0, 0, 0}, { 83, 65, 73, 0, 0, 0},
272 | { 83, 65, 78, 0, 0, 0}, { 83, 65, 78, 71, 0, 0},
273 | { 83, 65, 79, 0, 0, 0}, { 83, 69, 0, 0, 0, 0},
274 | { 83, 69, 78, 0, 0, 0}, { 83, 69, 78, 71, 0, 0},
275 | { 83, 72, 65, 0, 0, 0}, { 83, 72, 65, 73, 0, 0},
276 | { 83, 72, 65, 78, 0, 0}, { 83, 72, 65, 78, 71, 0},
277 | { 83, 72, 65, 79, 0, 0}, { 83, 72, 69, 0, 0, 0},
278 | { 83, 72, 69, 78, 0, 0}, { 88, 73, 78, 0, 0, 0},
279 | { 83, 72, 69, 78, 0, 0}, { 83, 72, 69, 78, 71, 0},
280 | { 83, 72, 73, 0, 0, 0}, { 83, 72, 79, 85, 0, 0},
281 | { 83, 72, 85, 0, 0, 0}, { 83, 72, 85, 65, 0, 0},
282 | { 83, 72, 85, 65, 73, 0}, { 83, 72, 85, 65, 78, 0},
283 | { 83, 72, 85, 65, 78, 71}, { 83, 72, 85, 73, 0, 0},
284 | { 83, 72, 85, 78, 0, 0}, { 83, 72, 85, 79, 0, 0},
285 | { 83, 73, 0, 0, 0, 0}, { 83, 79, 78, 71, 0, 0},
286 | { 83, 79, 85, 0, 0, 0}, { 83, 85, 0, 0, 0, 0},
287 | { 83, 85, 65, 78, 0, 0}, { 83, 85, 73, 0, 0, 0},
288 | { 83, 85, 78, 0, 0, 0}, { 83, 85, 79, 0, 0, 0},
289 | { 84, 65, 0, 0, 0, 0}, { 84, 65, 73, 0, 0, 0},
290 | { 84, 65, 78, 0, 0, 0}, { 84, 65, 78, 71, 0, 0},
291 | { 84, 65, 79, 0, 0, 0}, { 84, 69, 0, 0, 0, 0},
292 | { 84, 69, 78, 71, 0, 0}, { 84, 73, 0, 0, 0, 0},
293 | { 84, 73, 65, 78, 0, 0}, { 84, 73, 65, 79, 0, 0},
294 | { 84, 73, 69, 0, 0, 0}, { 84, 73, 78, 71, 0, 0},
295 | { 84, 79, 78, 71, 0, 0}, { 84, 79, 85, 0, 0, 0},
296 | { 84, 85, 0, 0, 0, 0}, { 84, 85, 65, 78, 0, 0},
297 | { 84, 85, 73, 0, 0, 0}, { 84, 85, 78, 0, 0, 0},
298 | { 84, 85, 79, 0, 0, 0}, { 87, 65, 0, 0, 0, 0},
299 | { 87, 65, 73, 0, 0, 0}, { 87, 65, 78, 0, 0, 0},
300 | { 87, 65, 78, 71, 0, 0}, { 87, 69, 73, 0, 0, 0},
301 | { 87, 69, 78, 0, 0, 0}, { 87, 69, 78, 71, 0, 0},
302 | { 87, 79, 0, 0, 0, 0}, { 87, 85, 0, 0, 0, 0},
303 | { 88, 73, 0, 0, 0, 0}, { 88, 73, 65, 0, 0, 0},
304 | { 88, 73, 65, 78, 0, 0}, { 88, 73, 65, 78, 71, 0},
305 | { 88, 73, 65, 79, 0, 0}, { 88, 73, 69, 0, 0, 0},
306 | { 88, 73, 78, 0, 0, 0}, { 88, 73, 78, 71, 0, 0},
307 | { 88, 73, 79, 78, 71, 0}, { 88, 73, 85, 0, 0, 0},
308 | { 88, 85, 0, 0, 0, 0}, { 88, 85, 65, 78, 0, 0},
309 | { 88, 85, 69, 0, 0, 0}, { 88, 85, 78, 0, 0, 0},
310 | { 89, 65, 0, 0, 0, 0}, { 89, 65, 78, 0, 0, 0},
311 | { 89, 65, 78, 71, 0, 0}, { 89, 65, 79, 0, 0, 0},
312 | { 89, 69, 0, 0, 0, 0}, { 89, 73, 0, 0, 0, 0},
313 | { 89, 73, 78, 0, 0, 0}, { 89, 73, 78, 71, 0, 0},
314 | { 89, 79, 0, 0, 0, 0}, { 89, 79, 78, 71, 0, 0},
315 | { 89, 79, 85, 0, 0, 0}, { 89, 85, 0, 0, 0, 0},
316 | { 89, 85, 65, 78, 0, 0}, { 89, 85, 69, 0, 0, 0},
317 | { 89, 85, 78, 0, 0, 0}, { 74, 85, 78, 0, 0, 0},
318 | { 89, 85, 78, 0, 0, 0}, { 90, 65, 0, 0, 0, 0},
319 | { 90, 65, 73, 0, 0, 0}, { 90, 65, 78, 0, 0, 0},
320 | { 90, 65, 78, 71, 0, 0}, { 90, 65, 79, 0, 0, 0},
321 | { 90, 69, 0, 0, 0, 0}, { 90, 69, 73, 0, 0, 0},
322 | { 90, 69, 78, 0, 0, 0}, { 90, 69, 78, 71, 0, 0},
323 | { 90, 72, 65, 0, 0, 0}, { 90, 72, 65, 73, 0, 0},
324 | { 90, 72, 65, 78, 0, 0}, { 90, 72, 65, 78, 71, 0},
325 | { 67, 72, 65, 78, 71, 0}, { 90, 72, 65, 78, 71, 0},
326 | { 90, 72, 65, 79, 0, 0}, { 90, 72, 69, 0, 0, 0},
327 | { 90, 72, 69, 78, 0, 0}, { 90, 72, 69, 78, 71, 0},
328 | { 90, 72, 73, 0, 0, 0}, { 83, 72, 73, 0, 0, 0},
329 | { 90, 72, 73, 0, 0, 0}, { 90, 72, 79, 78, 71, 0},
330 | { 90, 72, 79, 85, 0, 0}, { 90, 72, 85, 0, 0, 0},
331 | { 90, 72, 85, 65, 0, 0}, { 90, 72, 85, 65, 73, 0},
332 | { 90, 72, 85, 65, 78, 0}, { 90, 72, 85, 65, 78, 71},
333 | { 90, 72, 85, 73, 0, 0}, { 90, 72, 85, 78, 0, 0},
334 | { 90, 72, 85, 79, 0, 0}, { 90, 73, 0, 0, 0, 0},
335 | { 90, 79, 78, 71, 0, 0}, { 90, 79, 85, 0, 0, 0},
336 | { 90, 85, 0, 0, 0, 0}, { 90, 85, 65, 78, 0, 0},
337 | { 90, 85, 73, 0, 0, 0}, { 90, 85, 78, 0, 0, 0},
338 | { 90, 85, 79, 0, 0, 0}, { 0, 0, 0, 0, 0, 0},
339 | { 83, 72, 65, 78, 0, 0}, { 0, 0, 0, 0, 0, 0}, };
340 |
341 | /** First and last Chinese character with known Pinyin according to zh collation */
342 | private static final String FIRST_PINYIN_UNIHAN = "\u963F";
343 | private static final String LAST_PINYIN_UNIHAN = "\u9FFF";
344 |
345 | private static final Collator COLLATOR = Collator.getInstance(Locale.CHINA);
346 |
347 | private static HanziToPinyin3 sInstance;
348 | private final boolean mHasChinaCollator;
349 |
350 | public static class Token {
351 | /**
352 | * Separator between target string for each source char
353 | */
354 | public static final String SEPARATOR = " ";
355 |
356 | public static final int LATIN = 1;
357 | public static final int PINYIN = 2;
358 | public static final int UNKNOWN = 3;
359 |
360 | public Token() {
361 | }
362 |
363 | public Token(int type, String source, String target) {
364 | this.type = type;
365 | this.source = source;
366 | this.target = target;
367 | }
368 |
369 | /**
370 | * Type of this token, ASCII, PINYIN or UNKNOWN.
371 | */
372 | public int type;
373 | /**
374 | * Original string before translation.
375 | */
376 | public String source;
377 | /**
378 | * Translated string of source. For Han, target is corresponding Pinyin. Otherwise target is
379 | * original string in source.
380 | */
381 | public String target;
382 | }
383 |
384 | protected HanziToPinyin3(boolean hasChinaCollator) {
385 | mHasChinaCollator = hasChinaCollator;
386 | }
387 |
388 | public static HanziToPinyin3 getInstance() {
389 | synchronized (HanziToPinyin3.class) {
390 | if (sInstance != null) {
391 | return sInstance;
392 | }
393 | // Check if zh_CN collation data is available
394 | final Locale locale[] = Collator.getAvailableLocales();
395 | for (int i = 0; i < locale.length; i++) {
396 | if (locale[i].equals(Locale.CHINA)) {
397 | // Do self validation just once.
398 | if (DEBUG) {
399 | Log.d(TAG, "Self validation. Result: " + doSelfValidation());
400 | }
401 | sInstance = new HanziToPinyin3(true);
402 | return sInstance;
403 | }
404 | }
405 | Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");
406 | sInstance = new HanziToPinyin3(false);
407 | return sInstance;
408 | }
409 | }
410 |
411 | /**
412 | * Validate if our internal table has some wrong value.
413 | *
414 | * @return true when the table looks correct.
415 | */
416 | private static boolean doSelfValidation() {
417 | char lastChar = UNIHANS[0];
418 | String lastString = Character.toString(lastChar);
419 | for (char c : UNIHANS) {
420 | if (lastChar == c) {
421 | continue;
422 | }
423 | final String curString = Character.toString(c);
424 | int cmp = COLLATOR.compare(lastString, curString);
425 | if (cmp >= 0) {
426 | Log.e(TAG, "Internal error in Unihan table. " + "The last string \"" + lastString
427 | + "\" is greater than current string \"" + curString + "\".");
428 | return false;
429 | }
430 | lastString = curString;
431 | }
432 | return true;
433 | }
434 |
435 | private Token getToken(char character) {
436 | Token token = new Token();
437 | final String letter = Character.toString(character);
438 | token.source = letter;
439 | int offset = -1;
440 | int cmp;
441 | if (character < 256) {
442 | token.type = Token.LATIN;
443 | token.target = letter;
444 | return token;
445 | } else {
446 | cmp = COLLATOR.compare(letter, FIRST_PINYIN_UNIHAN);
447 | if (cmp < 0) {
448 | token.type = Token.UNKNOWN;
449 | token.target = letter;
450 | return token;
451 | } else if (cmp == 0) {
452 | token.type = Token.PINYIN;
453 | offset = 0;
454 | } else {
455 | cmp = COLLATOR.compare(letter, LAST_PINYIN_UNIHAN);
456 | if (cmp > 0) {
457 | token.type = Token.UNKNOWN;
458 | token.target = letter;
459 | return token;
460 | } else if (cmp == 0) {
461 | token.type = Token.PINYIN;
462 | offset = UNIHANS.length - 1;
463 | }
464 | }
465 | }
466 |
467 | token.type = Token.PINYIN;
468 | if (offset < 0) {
469 | int begin = 0;
470 | int end = UNIHANS.length - 1;
471 | while (begin <= end) {
472 | offset = (begin + end) / 2;
473 | final String unihan = Character.toString(UNIHANS[offset]);
474 | cmp = COLLATOR.compare(letter, unihan);
475 | if (cmp == 0) {
476 | break;
477 | } else if (cmp > 0) {
478 | begin = offset + 1;
479 | } else {
480 | end = offset - 1;
481 | }
482 | }
483 | }
484 | if (cmp < 0) {
485 | offset--;
486 | }
487 | StringBuilder pinyin = new StringBuilder();
488 | for (int j = 0; j < PINYINS[offset].length && PINYINS[offset][j] != 0; j++) {
489 | pinyin.append((char) PINYINS[offset][j]);
490 | }
491 | token.target = pinyin.toString();
492 | if (TextUtils.isEmpty(token.target)) {
493 | token.type = Token.UNKNOWN;
494 | token.target = token.source;
495 | }
496 | return token;
497 | }
498 |
499 | /**
500 | * Convert the input to a array of tokens. The sequence of ASCII or Unknown characters without
501 | * space will be put into a Token, One Hanzi character which has pinyin will be treated as a
502 | * Token. If these is no China collator, the empty token array is returned.
503 | */
504 | public ArrayList get(final String input) {
505 | ArrayList tokens = new ArrayList();
506 | if (!mHasChinaCollator || TextUtils.isEmpty(input)) {
507 | // return empty tokens.
508 | return tokens;
509 | }
510 | final int inputLength = input.length();
511 | final StringBuilder sb = new StringBuilder();
512 | int tokenType = Token.LATIN;
513 | // Go through the input, create a new token when
514 | // a. Token type changed
515 | // b. Get the Pinyin of current charater.
516 | // c. current character is space.
517 | for (int i = 0; i < inputLength; i++) {
518 | final char character = input.charAt(i);
519 | if (character == ' ') {
520 | if (sb.length() > 0) {
521 | addToken(sb, tokens, tokenType);
522 | }
523 | } else if (character < 256) {
524 | if (tokenType != Token.LATIN && sb.length() > 0) {
525 | addToken(sb, tokens, tokenType);
526 | }
527 | tokenType = Token.LATIN;
528 | sb.append(character);
529 | } else {
530 | Token t = getToken(character);
531 | if (t.type == Token.PINYIN) {
532 | if (sb.length() > 0) {
533 | addToken(sb, tokens, tokenType);
534 | }
535 | tokens.add(t);
536 | tokenType = Token.PINYIN;
537 | } else {
538 | if (tokenType != t.type && sb.length() > 0) {
539 | addToken(sb, tokens, tokenType);
540 | }
541 | tokenType = t.type;
542 | sb.append(character);
543 | }
544 | }
545 | }
546 | if (sb.length() > 0) {
547 | addToken(sb, tokens, tokenType);
548 | }
549 | return tokens;
550 | }
551 |
552 | private void addToken(
553 | final StringBuilder sb, final ArrayList tokens, final int tokenType) {
554 | String str = sb.toString();
555 | tokens.add(new Token(tokenType, str, str));
556 | sb.setLength(0);
557 | }
558 | }
559 |
--------------------------------------------------------------------------------
/CityList/src/com/liucanwen/citylist/widget/pinyin/PinYin.java:
--------------------------------------------------------------------------------
1 | package com.liucanwen.citylist.widget.pinyin;
2 |
3 | import java.util.ArrayList;
4 |
5 | import com.liucanwen.citylist.widget.pinyin.HanziToPinyin3.Token;
6 |
7 | public class PinYin
8 | {
9 | // 汉字返回拼音,字母原样返回,都转换为小写
10 | public static String getPinYin(String input)
11 | {
12 | ArrayList tokens = HanziToPinyin3.getInstance().get(input);
13 | StringBuilder sb = new StringBuilder();
14 | if (tokens != null && tokens.size() > 0)
15 | {
16 | for (Token token : tokens)
17 | {
18 | if (Token.PINYIN == token.type)
19 | {
20 | sb.append(token.target);
21 | } else
22 | {
23 | sb.append(token.source);
24 | }
25 | }
26 | }
27 | return sb.toString().toLowerCase();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 中国城市列表,类似手机通讯录显示方式,可以通过触摸屏幕右边城市拼音首字母快速定位,还可通过中文、拼音快速查找。
2 |
3 | * * *
4 |
5 | 显示效果:
6 |
7 | 
8 |
9 | 联系邮箱:
10 | liucanwen517@gmail.com
11 |
--------------------------------------------------------------------------------
/all_screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/all_screenshot.jpg
--------------------------------------------------------------------------------
/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/screenshot1.png
--------------------------------------------------------------------------------
/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/screenshot2.png
--------------------------------------------------------------------------------
/screenshot3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kk-java/ChineseCityList/ee00f5bd42e38b1816776a0dfde61673f353f672/screenshot3.png
--------------------------------------------------------------------------------