今天记录一个ListView的查询与更新的代码,ListView里显示的是城市名,然后在EditText里输入城市名,从ListView显示的城市中查询对应的城市并更新ListView显示,效果图如下:
1、首先是布局文件,很简单,activity_main.xml文件的内容如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:fitsSystemWindows="true" android:clipToPadding="true" android:background="@color/white" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/searchEt" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:hint="输入城市名来查询" /> <ListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:dividerHeight="0.8dp" /> </LinearLayout>
3、解析上面的cities.xml文件然后在ListView中显示,这里使用的Android的pull解析,如果不会的话,在我的另一篇博文中有记录:http://blog.csdn.net/yubo_725/article/details/41675225
解析xml的代码如下:
private class ParseXmlTask extends AsyncTask<Void, Void, Void>{ private XmlPullParser pullParser; private List<ProvinceBean> provinceList; private ProvinceBean province; private CityBean city; private CountyBean county; public ParseXmlTask(){ provinceList = new ArrayList<ProvinceBean>(); } @Override protected void onPreExecute() { super.onPreExecute(); pullParser = Xml.newPullParser(); InputStream is = getResources().openRawResource(R.raw.cities); try { pullParser.setInput(is, "UTF-8"); } catch (XmlPullParserException e) { e.printStackTrace(); } pd.show(); } @Override protected Void doInBackground(Void... arg0) { int eventType = 1; try { eventType = pullParser.getEventType(); } catch (XmlPullParserException e) { e.printStackTrace(); } while(eventType != XmlPullParser.END_DOCUMENT){ switch(eventType){ case XmlPullParser.START_TAG: String startTag = pullParser.getName(); if("province".equals(startTag)){ province = new ProvinceBean(); province.setId(pullParser.getAttributeValue(null, "id")); province.setName(pullParser.getAttributeValue(null, "name")); }else if("city".equals(startTag)){ city = new CityBean(); city.setId(pullParser.getAttributeValue(null, "id")); city.setName(pullParser.getAttributeValue(null, "name")); }else if("county".equals(startTag)){ county = new CountyBean(); county.setId(pullParser.getAttributeValue(null, "id")); county.setName(pullParser.getAttributeValue(null, "name")); county.setWeatherCode(pullParser.getAttributeValue(null, "weatherCode")); if(city != null){ city.getCountyList().add(county); } } break; case XmlPullParser.END_TAG: String endTag = pullParser.getName(); if("city".equals(endTag) && province != null){ province.getCityList().add(city); }else if("province".equals(endTag) && province != null){ provinceList.add(province); } break; } try { eventType = pullParser.next(); } catch (Exception e) { e.printStackTrace(); } } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); pd.dismiss(); int cityCount = 0; int countyCount = 0; List<BaseBean> list = new ArrayList<BaseBean>(); if(provinceList != null){ Log.d("yubo", "province count = " + provinceList.size()); for(ProvinceBean province : provinceList){ List<CityBean> cityList = province.getCityList(); cityCount += cityList.size(); for(CityBean city : cityList){ countyCount += city.getCountyList().size(); list.add(city); } } Log.d("yubo", "city count = " + cityCount); Log.d("yubo", "county count = " + countyCount); showListView(list); } } }主要是在AsyncTask中解析xml,上面涉及到三个JavaBean,分别是ProvinceBean、CityBean和CountyBean,这三个JavaBean都继承BaseBean,其中的字段有:
然后是在ListView中显示解析出的城市名,这里的list_item布局文件就是一个TextView,list_item.xml文件的内容如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/list_item_name" android:layout_width="fill_parent" android:layout_height="50dp" android:paddingLeft="15dp" android:textColor="#000000" android:textSize="15sp" android:gravity="center_vertical" /> </LinearLayout>为ListView设置适配器,这里用到了一个封装好的万能适配器类CommonAdapter,这个类的说明可以参考博文: http://blog.csdn.net/lmj623565791/article/details/38902805
我们的适配器代码如下:
package com.example.searchlistview.adapter; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.text.TextUtils; import android.widget.TextView; import com.example.searchlistview.R; import com.example.searchlistview.bean.BaseBean; import com.example.searchlistview.bean.CityBean; public class CityListAdapter extends CommonAdapter<BaseBean> { private List<BaseBean> allData; private List<BaseBean> queryData; public CityListAdapter(Context context, List<BaseBean> mDatas, int itemLayoutId) { super(context, mDatas, itemLayoutId); allData = mDatas; queryData = new ArrayList<BaseBean>(); } public void queryData(String query){ queryData.clear(); for(BaseBean bean : allData){ CityBean cityBean = (CityBean) bean; String name = cityBean.getName(); if(!TextUtils.isEmpty(name) && name.contains(query)){ queryData.add(bean); } } mDatas = queryData; notifyDataSetChanged(); } public void resetData(){ mDatas = allData; notifyDataSetChanged(); } @Override public void convert(ViewHolder holder, BaseBean item) { TextView nameTv = holder.getView(R.id.list_item_name); nameTv.setText(((CityBean)item).getName()); } }适配器里提供了一个resetData和一个queryData()方法,这两个方法用于在查询ListView时调用,下面是EditText的监听代码:
searchEt.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { if(adapter != null){ int len = arg0.length(); if(len == 0){ adapter.resetData(); }else if(len > 0){ adapter.queryData(arg0.toString()); } } } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) { } });监听EditText的输入事件,如果输入的为空,就显示ListView的所有数据,如果输入的不为空,则显示查询到的数据。
源代码下载