[置顶] Android afterTextChanged中逻辑卡顿的问题
2015-11-09 19:47
597 查看
最近在进行Android应用开发的过程中,遇到了一个问题,在这里我把它记录下来,希望可以给遇到相似问题的同学们一点启发,同时也是对自己做过的项目的一个小总结。
我的app有一个界面是完成一个搜索框,我没有使用系统自带的搜索框,而是自定义了个布局,它由一个EditText和一个ListView组成。在EditText的afterTextChanged函数里对我输入EditText的数据进行匹配,从而动态去刷新ListView的显示,显现出一个搜索框的效果。
在这里出现了一个问题,我在afterTextChanged 需要调用notifyDataSetChanged方法去刷新ListView的显示的时候,EditText和ListView的显示都出现了明显地卡顿,至少延迟个3到5秒,对体验造成了极大的影响。关于我的EditText的代码如下:
通过注释,我发现造成卡顿的原因是上面代码中的红色代码段,也就是listview刷新的代码造成了我们的listview和edittext的延迟。但是这段代码又是我这个实现搜索框的必要代码,几乎不能省去,为此,我还尝试了添加广播的方法,通过广播去通知listview的刷新,但还是一样的效果,在Edittext输入的时候会非常卡顿。
我觉得很奇怪,所以上网问了一些问题,但是很遗憾,几乎没有人回答,最后,我抱着试一试的心态在stackoverflow上问了这个问题,结果得到了别人的提醒:http://stackoverflow.com/questions/33558489/listview-notifydatasetchanged-very-slow-in-edittext-aftertextchanged-method 会不会是我添加监听的这段代码的位置防止错了呢?
在这里我还要贴上自己的一段代码:
其实就是标注了红色的onPostExecute方法,我原来是执行了个异步线程,然后在onPostExecute方法中添加了我的EditText的addTextChangedListener监听,如果把ddTextChangedListener监听移动到其他地方,比如我的oncreate这样的函数中去执行,发现明显的卡顿现象就缓解了~
我查了一下,发现的确有人跟我有类似的问题,其实我的问题不在于EditText,而有可能在与在异步线程的onPostExecute方法中调用adpter的刷新所致。
我的app有一个界面是完成一个搜索框,我没有使用系统自带的搜索框,而是自定义了个布局,它由一个EditText和一个ListView组成。在EditText的afterTextChanged函数里对我输入EditText的数据进行匹配,从而动态去刷新ListView的显示,显现出一个搜索框的效果。
在这里出现了一个问题,我在afterTextChanged 需要调用notifyDataSetChanged方法去刷新ListView的显示的时候,EditText和ListView的显示都出现了明显地卡顿,至少延迟个3到5秒,对体验造成了极大的影响。关于我的EditText的代码如下:
searchWord.addTextChangedListener(new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void afterTextChanged(Editable s) { if (s.length() == 0) { ivDeleteText.setVisibility(View.GONE); } else { ivDeleteText.setVisibility(View.VISIBLE); } if (s.length() > 0) { searchData.clear(); for (int i = 0; i < data.size(); i++) { if (data.get(i).get("name").toString().contains(s.toString())) { searchData.add(data.get(i)); } } } else { searchData.clear(); citys_bg.setVisibility(View.VISIBLE); letter_view.setVisibility(View.VISIBLE); } <span style="color:#ff0000;">mAdapter.notifyDataSetChanged();</span> citys_bg.setVisibility(View.GONE); letter_view.setVisibility(View.INVISIBLE); } });
通过注释,我发现造成卡顿的原因是上面代码中的红色代码段,也就是listview刷新的代码造成了我们的listview和edittext的延迟。但是这段代码又是我这个实现搜索框的必要代码,几乎不能省去,为此,我还尝试了添加广播的方法,通过广播去通知listview的刷新,但还是一样的效果,在Edittext输入的时候会非常卡顿。
我觉得很奇怪,所以上网问了一些问题,但是很遗憾,几乎没有人回答,最后,我抱着试一试的心态在stackoverflow上问了这个问题,结果得到了别人的提醒:http://stackoverflow.com/questions/33558489/listview-notifydatasetchanged-very-slow-in-edittext-aftertextchanged-method 会不会是我添加监听的这段代码的位置防止错了呢?
在这里我还要贴上自己的一段代码:
private class MyTask extends AsyncTask<String, ArrayList<HashMap<String, Object>>, ArrayList<HashMap<String, Object>>> { //onPreExecute方法用于在执行后台任务前做一些UI操作 @Override protected void onPreExecute() { Utils.startProgress(FindGartenActivity.this); } //doInBackground方法内部执行后台任务,不可在此方法内修改UI @Override protected ArrayList<HashMap<String, Object>> doInBackground(String... params) { //在这里做数据库的加载 dbm=new DBManager(getApplicationContext()); SQLiteDatabase db=dbm.openDatabase(); ArrayList<HashMap<String, Object>> temp_data = new ArrayList<HashMap<String, Object>>(); Cursor cs=db.rawQuery("select * from nbg_district where id = 1 or id = 2 or id = 22 or id = 9 or id = 33 or id = 34 or(level = 2 and upid != 1 and upid != 2 and upid != 22 and upid != 9 and upid != 35 and upid != 36 and upid != 33 and upid != 34)", null); temp_data.clear(); while(cs.moveToNext()){ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("id",cs.getInt(0)); map.put("name", cs.getString(1)); map.put("level", cs.getInt(2)); map.put("usetype", cs.getInt(3)); map.put("upid", cs.getInt(4)); map.put("alpha", NameSort.getFirstPY(cs.getString(1)).toUpperCase()); temp_data.add(map); } SortNames(temp_data); cs.close(); return temp_data; } //onProgressUpdate方法用于更新进度信息 @Override protected void onProgressUpdate(ArrayList<HashMap<String, Object>>... values) { super.onProgressUpdate(values); } //onPostExecute方法用于在执行完后台任务后更新UI,显示结果 @Override protected void <span style="color:#ff0000;">onPostExecute</span>(ArrayList<HashMap<String, Object>> result) { data = result; initOverlay(); handler = new Handler(); overlayThread = new OverlayThread(); letter_view.setOnTouchingLetterChangedListener(new LetterListViewListener()); adapter = new TeamManagerListViewAdapter(data, FindGartenActivity.this); mListView.setAdapter(mAdapter); list_content.setAdapter(adapter); list_content.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { chooseSecondDistrict(Integer.parseInt(data.get(position).get("id").toString()), data.get(position).get("name").toString()); } }); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { chooseSecondDistrict(Integer.parseInt(searchData.get(position).get("id").toString()), data.get(position).get("name").toString()); } }); startLocate(); //创建一个数组,它的长度是position,它的每个元素代表了position到0的距离。 heights = new int[data.size()]; int preheight = 0; for(int i = 0; i < data.size(); i++){ View item = adapter.getView(i, null, list_content); item.measure(0, 0); if(i > 0){ preheight = heights[i- 1]; } heights[i] = item.getMeasuredHeight() + preheight; } } //onCancelled方法用于在取消执行中的任务时更改UI @Override protected void onCancelled() { } }
其实就是标注了红色的onPostExecute方法,我原来是执行了个异步线程,然后在onPostExecute方法中添加了我的EditText的addTextChangedListener监听,如果把ddTextChangedListener监听移动到其他地方,比如我的oncreate这样的函数中去执行,发现明显的卡顿现象就缓解了~
我查了一下,发现的确有人跟我有类似的问题,其实我的问题不在于EditText,而有可能在与在异步线程的onPostExecute方法中调用adpter的刷新所致。
相关文章推荐
- Trinea性能优化之Java(Android)代码优化
- 【基于Jsoup】Android通过Jsoup抓取网页信息详解(一)
- android5.1系统定制应用全屏界面实现禁止状态栏下拉
- aq-Android版本检测升级
- Android-如何将android studio项目上传至github
- android 自定义 环形进度条
- Error: Activity class {XXX} does not exist的问题解决
- Android 之 text relocations的简单解决方法
- Android. ImageView with SVG Support
- android如何让后台服务service不被杀死(设置前台服务)
- 使用Android Studio搭建Android5.0集成开发环境
- Android自定义progress
- Android自定义相机,切换前后摄像头,照相机拍照
- Intent
- 详解Android中Service组件(一)
- android开发遇到的问题
- Android设备二维码扫描竖屏显示
- android判断当前应用在前台还是后台
- Android 计算器的开发
- Android监听程序进入后台