Android Studio 仿首页美团切换城市(ListView)+数据库帮助类SQLiteOpenHelper+LetterView(字母排序) 您所在的位置:网站首页 手机美团不能切换定位城市 Android Studio 仿首页美团切换城市(ListView)+数据库帮助类SQLiteOpenHelper+LetterView(字母排序)

Android Studio 仿首页美团切换城市(ListView)+数据库帮助类SQLiteOpenHelper+LetterView(字母排序)

2024-06-13 01:52| 来源: 网络整理| 查看: 265

一、测试 1.首页美团切换城市: 2.实现: 二、项目:

三、理解 1、高德地图定位的使用 1.添加依赖库 2.启动显示定位城市名的代码,可以在高德地图官网开放平台获取,点击链接:Android 高德地图(带有定位和点击显示经度纬度) (1)依赖库: (1).1 在AndroidManifest.xml中添加: (1).1.1 添加定位权限

(1).1.2 在application上添加,1.输入高德地图的key 2.定位需要的服务

(2)启动显示定位城市名:

private void initLocation() { //初始化client locationClient = new AMapLocationClient(mContext); locationOption = getDefaultOption(); //设置定位参数 locationClient.setLocationOption(locationOption); // 设置定位监听 locationClient.setLocationListener(locationListener); } /** * 默认的定位参数 * * @author hongming.wang * @since 2.8.0 */ private AMapLocationClientOption getDefaultOption() { AMapLocationClientOption mOption = new AMapLocationClientOption(); mOption.setLocationMode(AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式 mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭 mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效 mOption.setInterval(2000);//可选,设置定位间隔。默认为2秒 mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用 AMapLocationClientOption.setLocationProtocol(AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差 mOption.setLocationCacheEnable(true); //可选,设置是否使用缓存定位,默认为true mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);//可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言) return mOption; } /** * 定位监听 */ AMapLocationListener locationListener = new AMapLocationListener() { @Override public void onLocationChanged(AMapLocation location) { if (null != location) { //errorCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明 if (location.getErrorCode() == 0) { currentCity = location.getCity().substring(0, location.getCity().length() - 1); tvLocate.setText("当前定位城市"); tvCurrentLocateCity.setVisibility(View.VISIBLE); tvCurrentLocateCity.setText(currentCity); pbLocate.setVisibility(View.GONE); } else { //定位失败 tvLocate.setText("未定位到城市,请选择"); tvCurrentLocateCity.setVisibility(View.VISIBLE); tvCurrentLocateCity.setText("重新选择"); pbLocate.setVisibility(View.GONE); return; } } else { Toast.makeText(mContext, "定位失败", Toast.LENGTH_SHORT).show(); } } }; /** * 开始定位 * * @author hongming.wang * @since 2.8.0 */ private void startLocation() { //根据控件的选择,重新设置定位参数 // resetOption(); // 设置定位参数 locationClient.setLocationOption(locationOption); // 启动定位 locationClient.startLocation(); }

2、主活动适配器Adapter,CityListAdapter类有六个视图:

1.搜索结果列表展示,搜索城市名的拼音也可以 2.显示当前定位城市名,我使用的是高德地图的 3.最近访问城市 4.热门城市 5.全部城市,仅展示“全部城市这四个字” 6.数据库中所有的城市的名字展示

(1)搜索结果列表展示适配器Adapter,SearchResultAdapter.java

public class SearchResultAdapter extends BaseAdapter { private List mSearchList; private Context mContext; private LayoutInflater mInflater; public SearchResultAdapter(Context context,List searchList){ this.mSearchList=searchList; this.mContext=context; mInflater=LayoutInflater.from(mContext); } @Override public int getCount() { return mSearchList.size(); } @Override public Object getItem(int position) { return mSearchList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder=null; if(convertView==null){ viewHolder=new ViewHolder(); convertView=mInflater.inflate(R.layout.item_search_list,null); viewHolder.tvCityName=(TextView) convertView.findViewById(R.id.tv_city_name); convertView.setTag(viewHolder); }else{ viewHolder =(ViewHolder) convertView.getTag(); } viewHolder.tvCityName.setText(mSearchList.get(position).getName()); viewHolder.tvCityName.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext,mSearchList.get(position).getName(),Toast.LENGTH_SHORT).show(); } }); return convertView; } class ViewHolder{ LinearLayout ll_item; TextView tvCityName; } }

item_search_list.xml

(2)显示当前定位城市名

if (viewType == 0) {//view类型为0,也就是:当前定位城市的布局 convertView = View.inflate(mContext, R.layout.item_location_city, null); tvLocate = (TextView) convertView.findViewById(R.id.tv_locate); tvCurrentLocateCity = (TextView) convertView.findViewById(R.id.tv_current_locate_city); pbLocate = (ProgressBar) convertView.findViewById(R.id.pb_loacte); if (!isNeedRefresh) { tvLocate.setText("当前定位城市"); tvCurrentLocateCity.setVisibility(View.VISIBLE); tvCurrentLocateCity.setText(currentCity); pbLocate.setVisibility(View.GONE); } else { startLocation(); } tvCurrentLocateCity.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { pbLocate.setVisibility(View.VISIBLE); tvLocate.setText("正在定位"); tvCurrentLocateCity.setVisibility(View.GONE); startLocation(); } });

item_location_city.xml

(3)最近访问城市

else if (viewType == 1) {//最近访问城市 convertView = View.inflate(mContext, R.layout.item_recent_visit_city, null); TextView tvRecentVisitCity = (TextView) convertView.findViewById(R.id.tv_recent_visit_city); tvRecentVisitCity.setText("最近访问城市"); MyGridView gvRecentVisitCity = (MyGridView) convertView.findViewById(R.id.gv_recent_visit_city); gvRecentVisitCity.setAdapter(new RecentVisitCityAdapter(mContext, mRecentCityList));

(3).1 自定义的MyGridView类:

public class MyGridView extends GridView { public MyGridView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int measureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, measureSpec); } }

(3).2 item_recent_visit_city.xml:

(3).3 最后访问城市适配器Adapter,RecentVisitCityAdapter.java

public class RecentVisitCityAdapter extends BaseAdapter { private List mRecentVisitCityList; private LayoutInflater mInflater; private Context mContext; public RecentVisitCityAdapter(Context context, List recentVisitCityList) { this.mRecentVisitCityList=recentVisitCityList; this.mContext=context; mInflater=LayoutInflater.from(mContext); } @Override public int getCount() { return mRecentVisitCityList.size(); } @Override public Object getItem(int position) { return mRecentVisitCityList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder=null; if(convertView==null){ viewHolder=new ViewHolder(); convertView=mInflater.inflate(R.layout.item_city,null); viewHolder.tvCityName=(TextView) convertView.findViewById(R.id.tv_city_name); convertView.setTag(viewHolder); }else{ viewHolder=(ViewHolder) convertView.getTag(); } viewHolder.tvCityName.setText(mRecentVisitCityList.get(position)); viewHolder.tvCityName.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext,mRecentVisitCityList.get(position)+"",0).show(); } }); return convertView; } class ViewHolder{ TextView tvCityName; } }

(3).3.1 item_city.xml

item_selector.xml

(4)热门城市

else if (viewType == 2) {//热门城市 convertView = View.inflate(mContext, R.layout.item_recent_visit_city, null); TextView tvRecentVisitCity = (TextView) convertView.findViewById(R.id.tv_recent_visit_city); tvRecentVisitCity.setText("热门城市"); MyGridView gvRecentVisitCity = (MyGridView) convertView.findViewById(R.id.gv_recent_visit_city); gvRecentVisitCity.setAdapter(new HotCityAdapter(mContext, mHotCityList));

(4).1 item_recent_visit_city.xml(上面有) (4).2 自定义MyGridView代码(上面也有) (4).3 热门城市适配器Adapter,HotCityAdapter.java

public class HotCityAdapter extends BaseAdapter { private List mHotCityList; private LayoutInflater mInflater; private Context mContext; public HotCityAdapter(Context context, List hotCityList) { this.mHotCityList = hotCityList; this.mContext = context; mInflater = LayoutInflater.from(mContext); } @Override public int getCount() { return mHotCityList.size(); } @Override public Object getItem(int position) { return mHotCityList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = null; if (convertView == null) { viewHolder = new ViewHolder(); convertView = mInflater.inflate(R.layout.item_city, null); viewHolder.tvCityName = (TextView) convertView.findViewById(R.id.tv_city_name); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.tvCityName.setText(mHotCityList.get(position).getName()); viewHolder.tvCityName.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext,mHotCityList.get(position).getName() + "", 0).show(); } }); return convertView; } class ViewHolder { TextView tvCityName; } }

(4).4 item_city.xml(上面有) (5)全部城市,仅展示“全部城市这四个字”

else if (viewType == 3) { convertView = View.inflate(mContext, R.layout.item_all_city_textview, null);

item_all_city_textview.xml

(6)数据库中所有的城市的名字展示

else {//数据库中所有的城市的名字展示 if (convertView == null) { viewHolder = new ViewHolder(); convertView = View.inflate(mContext, R.layout.item_city_list, null); viewHolder.tvAlpha = (TextView) convertView.findViewById(R.id.tv_alpha); viewHolder.tvCityName = (TextView) convertView.findViewById(R.id.tv_city_name); viewHolder.llMain = (LinearLayout) convertView.findViewById(R.id.ll_main); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } if (position >= 1) { viewHolder.tvCityName.setText(mAllCityList.get(position).getName()); viewHolder.llMain.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, mAllCityList.get(position).getName(), Toast.LENGTH_SHORT).show(); } }); String currentStr = getAlpha(mAllCityList.get(position).getPinyin()); String previewStr = (position - 1) >= 0 ? getAlpha(mAllCityList .get(position - 1).getPinyin()) : " "; //如果当前的条目的城市名字的拼音的首字母和其前一条条目的城市的名字的拼音的首字母不相同,则将布局中的展示字母的TextView展示出来 if (!previewStr.equals(currentStr)) { viewHolder.tvAlpha.setVisibility(View.VISIBLE); viewHolder.tvAlpha.setText(currentStr); } else { viewHolder.tvAlpha.setVisibility(View.GONE); } } }

item_city_list.xml

3、自定义MyLetterView的视图代码:

public class MyLetterView extends View { private Paint mPaint; private boolean isShowBg = false;// 用于区分是否显示view的背景 private OnSlidingListener mOnSlidingListener;// 滑动此View的监听器 private int choose = -1;// 用于标记当前所选中的位置 private TextView mTvDialog;//用于接受从activity中传过来的,中间用于展示字母的textView //需要展示的数据 private String[] letter = {"定位", "最近", "热门", "全部", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "W", "X", "Y", "Z"}; public MyLetterView(Context context) { super(context); } public MyLetterView(Context context, AttributeSet attrs) { super(context, attrs); initPaint(); } public MyLetterView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } private void initPaint() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setTextSize(30); mPaint.setColor(Color.parseColor("#000000")); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //当此View被按下时所显示的背景颜色 if (isShowBg) { canvas.drawColor(Color.parseColor("#40000000")); } //计算每个字符所占的高度 float singleHeight = getHeight() / letter.length; int width = getWidth(); for (int i = 0; i int action = event.getAction(); int position = (int) (event.getY() / getHeight() * letter.length); int oldChoose = choose; switch (action) { case MotionEvent.ACTION_DOWN: isShowBg = true; if (oldChoose != position && mOnSlidingListener != null) { if (position > 0 && position mTvDialog.setVisibility(View.VISIBLE); mTvDialog.setText(letter[position]); } } invalidate(); } break; case MotionEvent.ACTION_MOVE: isShowBg = true; if (oldChoose != position && mOnSlidingListener != null) { if (position >= 0 && position mTvDialog.setVisibility(View.VISIBLE); mTvDialog.setText(letter[position]); } } invalidate(); } break; case MotionEvent.ACTION_UP: isShowBg = false; choose = -1; if (mTvDialog != null) { mTvDialog.setVisibility(View.GONE); } invalidate(); break; } return true; } //MyLetterView的一个滑动的监听 public void setOnSlidingListener(OnSlidingListener mOnSlidingListener) { this.mOnSlidingListener = mOnSlidingListener; } public interface OnSlidingListener { public void sliding(String str); } public void setTextView(TextView tvDialog) { mTvDialog = tvDialog; } }

4、在assets目录放在meituan_cities.db,点击链接直接下载:下载meituan_cities.db 在这里插入图片描述 meituan_cities.db打开看看: 5、数据库帮助类SQLiteOpenHelper有两种:

1.最近访问城市 2.所有的城市

(1)最近访问城市CitySqliteOpenHelper.java

public class CitySqliteOpenHelper extends SQLiteOpenHelper { public static final String DB_ALL_CITY_NAME = "city"; public static final int version = 1; public CitySqliteOpenHelper(Context context) { super(context, DB_ALL_CITY_NAME, null, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS recentcity (" + "id integer primary key autoincrement," + " name varchar(40)," + " date INTEGER)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }

(2)所有的城市AllCitySqliteOpenHelper.java

public class AllCitySqliteOpenHelper extends SQLiteOpenHelper { // 数据库文件目标存放路径为系统默认位置,com.droid 是你的包名 private static String DB_PATH = "/data/data/com.example.citylist/databases/"; private static String DB_NAME = "meituan_cities.db"; private Context mContext; private static String ASSETS_NAME = "meituan_cities.db"; private static final int DB_VERSION = 3; public AllCitySqliteOpenHelper(Context context, String name, CursorFactory factory, int version) { // 必须通过super调用父类当中的构造函数 super(context, name, null, version); this.mContext = context; } public AllCitySqliteOpenHelper(Context context, String name, int version) { this(context, name, null, version); } public AllCitySqliteOpenHelper(Context context, String name) { this(context, name, DB_VERSION); } public AllCitySqliteOpenHelper(Context context) { this(context, DB_PATH + DB_NAME); } public void createDataBase() throws IOException { boolean dbExist = checkDataBase(); if (dbExist) { // 数据库已存在,do nothing. } else { // 创建数据库 try { File dir = new File(DB_PATH); if (!dir.exists()) { dir.mkdirs(); } File dbf = new File(DB_PATH + DB_NAME); if (dbf.exists()) { dbf.delete(); } //通过openOrCreateDatabase方法将assets目录下的数据库,创建到系统默认的地方 SQLiteDatabase.openOrCreateDatabase(dbf, null); // 复制asseets中的db文件到DB_PATH下 copyDataBase(); } catch (IOException e) { throw new Error("数据库创建失败"); } } } // 检查数据库是否有效 private boolean checkDataBase() { SQLiteDatabase checkDB = null; String myPath = DB_PATH + DB_NAME; try { checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); } catch (SQLiteException e) { // database does't exist yet. } if (checkDB != null) { checkDB.close(); } return checkDB != null ? true : false; } //将assets目录下的城市的数据复制到所创建的数据库下 private void copyDataBase() throws IOException { // Open your local db as the input stream InputStream myInput = mContext.getAssets().open(ASSETS_NAME); // Path to the just created empty db String outFileName = DB_PATH + DB_NAME; // Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(outFileName); // transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } // Close the streams myOutput.flush(); myOutput.close(); myInput.close(); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }

6、实体类City.java

public class City { private String name;//城市的名字 private String pinyin;//城市名字的拼音 public City(String name, String pinyin) { super(); this.name = name; this.pinyin = pinyin; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPinyin() { return pinyin; } public void setPinyin(String pinyin) { this.pinyin = pinyin; } }

7、将字符串的中文转化为拼音,其他字符不变,需要添加拼音jar文件,直接下载,点击链接:下载pinyin4j-2.5.0.jar PingYinUtil.java

public class PingYinUtil { /** * 将字符串中的中文转化为拼音,其他字符不变 */ public static String getPingYin(String inputString) { HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.LOWERCASE); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); format.setVCharType(HanyuPinyinVCharType.WITH_V); Pattern p = Pattern.compile("^[\u4E00-\u9FA5A-Za-z_]+$"); Matcher matcher = p.matcher(inputString.substring(0, 1)); if (matcher.find()) { char[] input = inputString.trim().toCharArray(); String output = ""; try { for (int i = 0; i String[] temp = PinyinHelper.toHanyuPinyinStringArray( input[i], format); output += temp[0]; } else output += java.lang.Character.toString(input[i]); } } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } return output; } else { return ""; } } public static String converterToFirstSpell(String chines) { String pinyinName = ""; char[] nameChar = chines.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i try { pinyinName += PinyinHelper.toHanyuPinyinStringArray( nameChar[i], defaultFormat)[0].charAt(0); } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pinyinName += nameChar[i]; } } return pinyinName; } }

四、使用 1.初始化所有城市的适配器Adapter,完整的CityListAdapter.java

public class CityListAdapter extends BaseAdapter { private Context mContext; private List mAllCityList; private List mHotCityList; private List mRecentCityList; public HashMap alphaIndexer;// 存放存在的汉语拼音首字母和与之对应的列表位置 private String[] sections;// 存放存在的汉语拼音首字母 private String currentCity;//当前城市 private boolean isNeedRefresh;//当前定位的城市是否需要刷新 private TextView tvCurrentLocateCity; private ProgressBar pbLocate; private TextView tvLocate; private final int VIEW_TYPE = 5;//view的类型个数 private AMapLocationClient locationClient = null; private AMapLocationClientOption locationOption = null; public CityListAdapter(Context context, List allCityList, List hotCityList, List recentCityList) { this.mContext = context; this.mAllCityList = allCityList; this.mHotCityList = hotCityList; this.mRecentCityList = recentCityList; alphaIndexer = new HashMap(); sections = new String[allCityList.size()]; //这里的主要目的是将listview中要显示字母的条目保存下来,方便在滑动时获得位置,alphaIndexer在Acitivity有调用 for (int i = 0; i String name = getAlpha(mAllCityList.get(i).getPinyin()); alphaIndexer.put(name, i); sections[i] = name; } } isNeedRefresh = true; initLocation(); } @Override public int getViewTypeCount() { return VIEW_TYPE; } @Override public int getItemViewType(int position) { return position return mAllCityList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = null; int viewType = getItemViewType(position); if (viewType == 0) {//view类型为0,也就是:当前定位城市的布局 convertView = View.inflate(mContext, R.layout.item_location_city, null); tvLocate = (TextView) convertView.findViewById(R.id.tv_locate); tvCurrentLocateCity = (TextView) convertView.findViewById(R.id.tv_current_locate_city); pbLocate = (ProgressBar) convertView.findViewById(R.id.pb_loacte); if (!isNeedRefresh) { tvLocate.setText("当前定位城市"); tvCurrentLocateCity.setVisibility(View.VISIBLE); tvCurrentLocateCity.setText(currentCity); pbLocate.setVisibility(View.GONE); } else { startLocation(); } tvCurrentLocateCity.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { pbLocate.setVisibility(View.VISIBLE); tvLocate.setText("正在定位"); tvCurrentLocateCity.setVisibility(View.GONE); startLocation(); } }); } else if (viewType == 1) {//最近访问城市 convertView = View.inflate(mContext, R.layout.item_recent_visit_city, null); TextView tvRecentVisitCity = (TextView) convertView.findViewById(R.id.tv_recent_visit_city); tvRecentVisitCity.setText("最近访问城市"); MyGridView gvRecentVisitCity = (MyGridView) convertView.findViewById(R.id.gv_recent_visit_city); gvRecentVisitCity.setAdapter(new RecentVisitCityAdapter(mContext, mRecentCityList)); } else if (viewType == 2) {//热门城市 convertView = View.inflate(mContext, R.layout.item_recent_visit_city, null); TextView tvRecentVisitCity = (TextView) convertView.findViewById(R.id.tv_recent_visit_city); tvRecentVisitCity.setText("热门城市"); MyGridView gvRecentVisitCity = (MyGridView) convertView.findViewById(R.id.gv_recent_visit_city); gvRecentVisitCity.setAdapter(new HotCityAdapter(mContext, mHotCityList)); } else if (viewType == 3) {//全部城市,仅展示“全部城市这四个字” convertView = View.inflate(mContext, R.layout.item_all_city_textview, null); } else {//数据库中所有的城市的名字展示 if (convertView == null) { viewHolder = new ViewHolder(); convertView = View.inflate(mContext, R.layout.item_city_list, null); viewHolder.tvAlpha = (TextView) convertView.findViewById(R.id.tv_alpha); viewHolder.tvCityName = (TextView) convertView.findViewById(R.id.tv_city_name); viewHolder.llMain = (LinearLayout) convertView.findViewById(R.id.ll_main); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } if (position >= 1) { viewHolder.tvCityName.setText(mAllCityList.get(position).getName()); viewHolder.llMain.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, mAllCityList.get(position).getName(), Toast.LENGTH_SHORT).show(); } }); String currentStr = getAlpha(mAllCityList.get(position).getPinyin()); String previewStr = (position - 1) >= 0 ? getAlpha(mAllCityList .get(position - 1).getPinyin()) : " "; //如果当前的条目的城市名字的拼音的首字母和其前一条条目的城市的名字的拼音的首字母不相同,则将布局中的展示字母的TextView展示出来 if (!previewStr.equals(currentStr)) { viewHolder.tvAlpha.setVisibility(View.VISIBLE); viewHolder.tvAlpha.setText(currentStr); } else { viewHolder.tvAlpha.setVisibility(View.GONE); } } } return convertView; } // 获得汉语拼音首字母 private String getAlpha(String str) { if (str == null) { return "#"; } if (str.trim().length() == 0) { return "#"; } char c = str.trim().substring(0, 1).charAt(0); // 正则表达式,判断首字母是否是英文字母 Pattern pattern = Pattern.compile("^[A-Za-z]+$"); if (pattern.matcher(c + "").matches()) { return (c + "").toUpperCase(); } else if (str.equals("0")) { return "定位"; } else if (str.equals("1")) { return "最近"; } else if (str.equals("2")) { return "热门"; } else if (str.equals("3")) { return "全部"; } else { return "#"; } } class ViewHolder { TextView tvAlpha; TextView tvCityName; LinearLayout llMain; } private void initLocation() { //初始化client locationClient = new AMapLocationClient(mContext); locationOption = getDefaultOption(); //设置定位参数 locationClient.setLocationOption(locationOption); // 设置定位监听 locationClient.setLocationListener(locationListener); } /** * 默认的定位参数 * * @author hongming.wang * @since 2.8.0 */ private AMapLocationClientOption getDefaultOption() { AMapLocationClientOption mOption = new AMapLocationClientOption(); mOption.setLocationMode(AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式 mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭 mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效 mOption.setInterval(2000);//可选,设置定位间隔。默认为2秒 mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用 AMapLocationClientOption.setLocationProtocol(AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差 mOption.setLocationCacheEnable(true); //可选,设置是否使用缓存定位,默认为true mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);//可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言) return mOption; } /** * 定位监听 */ AMapLocationListener locationListener = new AMapLocationListener() { @Override public void onLocationChanged(AMapLocation location) { if (null != location) { //errorCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明 if (location.getErrorCode() == 0) { currentCity = location.getCity().substring(0, location.getCity().length() - 1); tvLocate.setText("当前定位城市"); tvCurrentLocateCity.setVisibility(View.VISIBLE); tvCurrentLocateCity.setText(currentCity); pbLocate.setVisibility(View.GONE); } else { //定位失败 tvLocate.setText("未定位到城市,请选择"); tvCurrentLocateCity.setVisibility(View.VISIBLE); tvCurrentLocateCity.setText("重新选择"); pbLocate.setVisibility(View.GONE); return; } } else { Toast.makeText(mContext, "定位失败", Toast.LENGTH_SHORT).show(); } } }; /** * 开始定位 * * @author hongming.wang * @since 2.8.0 */ private void startLocation() { //根据控件的选择,重新设置定位参数 // resetOption(); // 设置定位参数 locationClient.setLocationOption(locationOption); // 启动定位 locationClient.startLocation(); } }

2.主活动布局activity_main.xml

3.主活动MainActivity.java

public class MainActivity extends Activity { protected static final String TAG = "MainActivity"; private MyLetterView myLetterView;//自定义的View private TextView tvDialog;//主界面显示字母的TextView private ListView lvCity;//进行城市列表展示 private EditText etSearch; private ListView lvResult;//搜索结果列表展示 private TextView tvNoResult;//搜索无结果时文字展示 private List allCityList;//所有的城市 private List hotCityList;//热门城市列表 private List searchCityList;//搜索城市列表 private List recentCityList;//最近访问城市列表 public CitySqliteOpenHelper cityOpenHelper;//对保存了最近访问城市的数据库操作的帮助类 public SQLiteDatabase cityDb;//保存最近访问城市的数据库 public CityListAdapter cityListAdapter; public SearchResultAdapter searchResultAdapter; private boolean isScroll = false; private boolean mReady = false; private Handler handler; private OverlayThread overlayThread; //显示首字母对话框 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); initView(); initData(); setListener(); //初始化所有城市列表 initAllCityData(); initRecentVisitCityData();//初始化最近访问的城市数据 initHotCityData();//初始化热门城市 setAdapter();//设置适配器 mReady = true; } private void setAdapter() { cityListAdapter = new CityListAdapter(this, allCityList, hotCityList, recentCityList); searchResultAdapter = new SearchResultAdapter(this, searchCityList); lvCity.setAdapter(cityListAdapter); lvResult.setAdapter(searchResultAdapter); } private void initView() { myLetterView = (MyLetterView) findViewById(R.id.my_letterview); tvDialog = (TextView) findViewById(R.id.tv_dialog); myLetterView.setTextView(tvDialog); lvCity = (ListView) findViewById(R.id.lv_city); etSearch = (EditText) findViewById(R.id.et_search); lvResult = (ListView) findViewById(R.id.lv_result); tvNoResult = (TextView) findViewById(R.id.tv_noresult); } private void setListener() { //自定义myLetterView的一个监听 myLetterView.setOnSlidingListener(new OnSlidingListener() { @Override public void sliding(String s) { isScroll = false; if (cityListAdapter.alphaIndexer.get(s) != null) { //根据MyLetterView滑动到的数据获得ListView应该展示的位置 int position = cityListAdapter.alphaIndexer.get(s); //将listView展示到相应的位置 lvCity.setSelection(position); } } }); etSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (s.toString() == null || "".equals(s.toString())) { myLetterView.setVisibility(View.VISIBLE); lvCity.setVisibility(View.VISIBLE); lvResult.setVisibility(View.GONE); tvNoResult.setVisibility(View.GONE); } else { searchCityList.clear(); myLetterView.setVisibility(View.GONE); lvCity.setVisibility(View.GONE); getResultCityList(s.toString()); if (searchCityList.size() lvResult.setVisibility(View.VISIBLE); tvNoResult.setVisibility(View.GONE); searchResultAdapter.notifyDataSetChanged(); } } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }); lvCity.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == SCROLL_STATE_TOUCH_SCROLL || scrollState == SCROLL_STATE_FLING) { isScroll = true; } } @SuppressLint("DefaultLocale") @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (!isScroll) { return; } if (mReady) { String text; String name = allCityList.get(firstVisibleItem).getName(); String pinyin = allCityList.get(firstVisibleItem).getPinyin(); if (firstVisibleItem text = PingYinUtil.converterToFirstSpell(pinyin).substring(0, 1).toUpperCase(); } tvDialog.setText(text); tvDialog.setVisibility(View.VISIBLE); handler.removeCallbacks(overlayThread); // Toast.makeText(MainActivity.this,"测试",0).show(); // 延迟一秒后执行,让中间显示的TextView为不可见 handler.postDelayed(overlayThread, 1000); } } }); } private void initData() { cityOpenHelper = new CitySqliteOpenHelper(MainActivity.this); cityDb = cityOpenHelper.getWritableDatabase(); allCityList = new ArrayList(); hotCityList = new ArrayList(); searchCityList = new ArrayList(); recentCityList = new ArrayList(); handler = new Handler(); overlayThread = new OverlayThread(); } private void initAllCityData() { City city = new City("定位", "0"); // 当前定位城市 allCityList.add(city); city = new City("最近", "1"); allCityList.add(city); city = new City("热门", "2"); allCityList.add(city); city = new City("全部", "3"); allCityList.add(city); allCityList.addAll(getCityList()); } @SuppressWarnings("unchecked") private ArrayList getCityList() { SQLiteDatabase db; Cursor cursor = null; //获取assets目录下的数据库中的所有城市的openHelper AllCitySqliteOpenHelper op = new AllCitySqliteOpenHelper(MainActivity.this); ArrayList cityList = new ArrayList(); try { op.createDataBase(); db = op.getWritableDatabase(); cursor = db.rawQuery("select * from city", null); while (cursor.moveToNext()) { String cityName = cursor.getString(cursor.getColumnIndex("name")); String cityPinyin = cursor.getString(cursor.getColumnIndex("pinyin")); City city = new City(cityName, cityPinyin); cityList.add(city); } } catch (IOException e) { e.printStackTrace(); } finally { cursor.close(); } Collections.sort(cityList, comparator); return cityList; } private void initRecentVisitCityData() { InsertCity("北京"); InsertCity("上海"); InsertCity("广州"); SQLiteDatabase recentVisitDb = cityOpenHelper.getWritableDatabase(); Cursor cursor = recentVisitDb.rawQuery("select * from recentcity order by date desc limit 0, 3", null); while (cursor.moveToNext()) { String recentVisitCityName = cursor.getString(cursor.getColumnIndex("name")); recentCityList.add(recentVisitCityName); } cursor.close(); recentVisitDb.close(); } private void initHotCityData() { City city = new City("北京", "2"); hotCityList.add(city); city = new City("上海", "2"); hotCityList.add(city); city = new City("广州", "2"); hotCityList.add(city); city = new City("南京", "2"); hotCityList.add(city); city = new City("合肥", "2"); hotCityList.add(city); city = new City("安徽", "2"); hotCityList.add(city); city = new City("砀山", "2"); hotCityList.add(city); city = new City("日本", "2"); hotCityList.add(city); } /** * 自定义的排序规则,按照A-Z进行排序 */ @SuppressWarnings("rawtypes") Comparator comparator = new Comparator() { @Override public int compare(City lhs, City rhs) { String a = lhs.getPinyin().substring(0, 1); String b = rhs.getPinyin().substring(0, 1); int flag = a.compareTo(b); if (flag == 0) { return a.compareTo(b); } else { return flag; } } }; @SuppressWarnings("unchecked") private void getResultCityList(String keyword) { AllCitySqliteOpenHelper dbHelper = new AllCitySqliteOpenHelper(this); try { dbHelper.createDataBase(); SQLiteDatabase db = dbHelper.getWritableDatabase(); Cursor cursor = db.rawQuery( "select * from city where name like \"%" + keyword + "%\" or pinyin like \"%" + keyword + "%\"", null); City city; while (cursor.moveToNext()) { String cityName = cursor.getString(cursor.getColumnIndex("name")); String cityPinyin = cursor.getString(cursor.getColumnIndex("pinyin")); city = new City(cityName, cityPinyin); searchCityList.add(city); } cursor.close(); db.close(); } catch (IOException e) { e.printStackTrace(); } //将得到的集合按照自定义的comparator的规则进行排序 Collections.sort(searchCityList, comparator); } // 设置显示字母的TextView为不可见 private class OverlayThread implements Runnable { @Override public void run() { tvDialog.setVisibility(View.INVISIBLE); } } //插入数据到最近访问的城市 public void InsertCity(String name) { SQLiteDatabase db = cityOpenHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select * from recentcity where name = '" + name + "'", null); if (cursor.getCount() > 0) { // db.delete("recentcity", "name = ?", new String[]{name}); } db.execSQL("insert into recentcity(name, date) values('" + name + "', " + System.currentTimeMillis() + ")"); db.close(); } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有