android小知识之当一个listview对应两个adapter第一次加载时无item点击效果处理
先上图
简单介绍下遇见的问题:
第一次加载时默认显示我的提问,点击我的提问显示我的提问(貌似是废话)。两组数据共用一个listview(暂时先不考虑这合不合理),listview设有item监听,监听代码如下:
1 @Override 2 public void onItemClick(AdapterView<?> parent, View view, int position, 3 long id) { 4 5 if (((HeaderViewListAdapter)parent.getAdapter()).getWrappedAdapter() == adapter_ask) { 6 7 PersonCenterAsk askanswer = adapter_ask.getItem(position); 8 String tidname = askanswer.getTidname(); 9 long asktime = 1000 * askanswer.getDateline(); 10 String question = askanswer.getTitle(); 11 String asker = askanswer.getUname(); 12 int questionid = askanswer.getQuestionid(); 13 int tid = askanswer.getTid(); 14 Intent intent = new Intent(getActivity(), AskListItemActivity.class); 15 intent.putExtra("title", asker); 16 intent.putExtra("index", "myask");// 标志位,表示是从问答界面的item跳转的 17 18 SharedPreferences.Editor editor = getActivity() 19 .getSharedPreferences("askanswerInfo", Context.MODE_PRIVATE) 20 .edit(); 21 editor.putString("asker", asker); 22 editor.putString("question", question); 23 editor.putLong("asktime", asktime); 24 editor.putInt("questionid", questionid); 25 editor.putString("tidname", tidname); 26 editor.putInt("tid", tid); 27 editor.commit(); 28 startActivity(intent); 29 30 } else if (((HeaderViewListAdapter)parent.getAdapter()).getWrappedAdapter() == adapter_answer) { 31 32 PersonCenterAnswer answerask = adapter_answer.getItem(position); 33 String tidname = answerask.getTidname(); 34 long asktime = 1000 * answerask.getAsktime(); 35 String question = answerask.getTitle(); 36 String asker = answerask.getAsker(); 37 int questionid = answerask.getQuestionid(); 38 int tid = answerask.getTid(); 39 40 Intent intent = new Intent(getActivity(), AskListItemActivity.class); 41 intent.putExtra("title", asker); 42 intent.putExtra("index", "myanswer");// 标志位,表示是从问答界面的item跳转的 43 SharedPreferences.Editor editor = getActivity() 44 .getSharedPreferences("askanswerInfo", Context.MODE_PRIVATE) 45 .edit(); 46 editor.putString("asker", asker); 47 editor.putString("question", question); 48 editor.putLong("asktime", asktime); 49 editor.putInt("questionid", questionid); 50 editor.putString("tidname", tidname); 51 editor.putInt("tid", tid); 52 editor.commit(); 53 startActivity(intent); 54 55 } 56 57 }
很多时候我们会把上面的判别语句写成:parent.getAdapter()==adapter_ask 或者 list.getAdapter()==adapter_ask() ,在大多数情况下都可以成立的啊,之前我也是这么做的,然而在第一加载界面的时候死活item监听跳转没有执行,卡了很久。后来看源码才发现是我给setadapter之后listview添加了footview(事实上headerview 也会造成这种现象),这是源码:
1 if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) { 2 mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter); 3 } else { 4 mAdapter = adapter; 5 }
当给他设置了header或者footer的时候 就会把adapter转换成headerviewlistadapter,adapter的类型就变了,上面的蓝色判别代码永远都不会成立,自然点击item的跳转就不会执行了。
改进如下:
(HeaderViewListAdapter)parent.getAdapter()).getWrappedAdapter() == adapter_answer
这样强转后就很好很好的解决了判别当前点击item所处的adapter是谁。(整个过程中footerlistview 或 headerlistview不能移除,否则会出现类型转换异常)
其实上面的这种思路本身就是不好的,应该避免这样使用,一个listview搭配两个adapter组建两组数据本身就不值得提倡,完全可以写两个listview,各自对应自己的adapter和数据,item的监听类写成两个类部类,在点击radiobutton的时候显示或隐藏对应的listview,而所有数据在构件页面的时候去加载,个人觉得这样更好。
1 package com.yingjie.jzlfapp.ui.personcenter; 2 3 import java.lang.reflect.Type; 4 import java.util.List; 5 6 import android.content.Context; 7 import android.content.Intent; 8 import android.content.SharedPreferences; 9 import android.os.Bundle; 10 import android.support.v4.app.Fragment; 11 import android.view.LayoutInflater; 12 import android.view.View; 13 import android.view.ViewGroup; 14 import android.widget.AdapterView; 15 import android.widget.AbsListView.OnScrollListener; 16 import android.widget.AdapterView.OnItemClickListener; 17 import android.widget.AbsListView; 18 import android.widget.Button; 19 import android.widget.HeaderViewListAdapter; 20 import android.widget.ListView; 21 import android.widget.RadioGroup; 22 import android.widget.Toast; 23 import android.widget.RadioGroup.OnCheckedChangeListener; 24 import android.widget.TextView; 25 26 import com.android.volley.Request.Method; 27 import com.android.volley.RequestQueue; 28 import com.android.volley.Response; 29 import com.android.volley.VolleyError; 30 import com.android.volley.toolbox.StringRequest; 31 import com.baidu.mobstat.StatService; 32 import com.google.gson.Gson; 33 import com.google.gson.reflect.TypeToken; 34 import com.yingjie.jzlfapp.adapter.PersonCenterAnswerAdapter; 35 import com.yingjie.jzlfapp.adapter.PersonCenterQuestionAdapter; 36 import com.yingjie.jzlfapp.app.MyApp; 37 import com.yingjie.jzlfapp.model.local.LoginMessage; 38 import com.yingjie.jzlfapp.model.local.PersonCenterAnswer; 39 import com.yingjie.jzlfapp.model.local.PersonCenterAsk; 40 import com.yingjie.jzlfapp.ui.askanswer.AskListItemActivity; 41 import com.yingjie.jzlfxxt.R; 42 43 /** 44 * 45 * @ClassName: FragmentPersonCenterLogined 46 * @Description: 登陆成功后的出现的fragment 47 * @author ws 48 * @date 2014-1-3 上午11:45:34 49 * 50 */ 51 public class FragmentPersonCenterLogined extends Fragment implements 52 OnCheckedChangeListener { 53 private Button btn_myask; 54 private Button btn_myanswer; 55 private ListView lv_ask_answer; 56 private ListView lv_answer_ask; 57 private TextView tv_username; 58 59 private RadioGroup layoutbtn; 60 /** 61 * 适配器 62 */ 63 private PersonCenterQuestionAdapter adapter_ask; 64 private PersonCenterAnswerAdapter adapter_answer; 65 66 /** 67 * 数据库读取 68 */ 69 private static int RESULTS_PAGE_SIZE = 8; 70 private String ask_url; 71 private String answer_url; 72 private String myName; 73 private View lvNews_footer; 74 75 @Override 76 public View onCreateView(LayoutInflater inflater, ViewGroup container, 77 Bundle savedInstanceState) { 78 View view = inflater.inflate(R.layout.personcenter_fragment_logined, 79 container, false); 80 tv_username = (TextView) view.findViewById(R.id.personcenter_username); 81 myName = LoginMessage.getUserName(); 82 tv_username.setText(myName); 83 layoutbtn = (RadioGroup) view.findViewById(R.id.personcenter_layoutbtn); 84 layoutbtn.setOnCheckedChangeListener(this); 85 btn_myask = (Button) view.findViewById(R.id.personcenter_myask); 86 btn_myanswer = (Button) view.findViewById(R.id.personcenter_myanswer); 87 88 lv_ask_answer = (ListView) view.findViewById(R.id.ask_answer); 89 lv_ask_answer.setOnScrollListener(new EndlessScrollListener()); 90 lv_ask_answer.setOnItemClickListener(new AskonItemClickListener()); 91 ask_url = getActivity().getResources().getString( 92 R.string.personcenter_myask_url); 93 94 lv_answer_ask = (ListView) view.findViewById(R.id.answer_ask); 95 lv_answer_ask.setOnScrollListener(new EndlessAnswerScrollListener()); 96 lv_answer_ask.setOnItemClickListener(new AnswerOnItemClickListener()); 97 98 adapter_ask = new PersonCenterQuestionAdapter(getActivity()); 99 lv_ask_answer.setAdapter(adapter_ask); 100 101 adapter_answer = new PersonCenterAnswerAdapter(getActivity()); 102 lv_answer_ask.setAdapter(adapter_answer); 103 104 answer_url = getActivity().getResources().getString( 105 R.string.personcenter_myanswer_url); 106 107 lvNews_footer = (getActivity().getLayoutInflater().inflate( 108 R.layout.listview_footer, null)); 109 110 lv_ask_answer.addFooterView(lvNews_footer); 111 lv_answer_ask.addFooterView(lvNews_footer); 112 113 loadData(); 114 115 return view; 116 } 117 118 public void onCheckedChanged(RadioGroup group, int checkedId) { 119 120 switch (checkedId) { 121 // 我的提问 122 case R.id.personcenter_myask: 123 btn_myanswer.setBackgroundResource(R.drawable.button_answer_normal); 124 btn_myask.setBackgroundResource(R.drawable.button_answer_pressed); 125 lv_ask_answer.setVisibility(View.VISIBLE); 126 lv_answer_ask.setVisibility(View.GONE); 127 128 break; 129 case R.id.personcenter_myanswer: 130 // 我的回答 131 btn_myask.setBackgroundResource(R.drawable.button_answer_normal); 132 btn_myanswer 133 .setBackgroundResource(R.drawable.button_answer_pressed); 134 lv_ask_answer.setVisibility(View.GONE); 135 lv_answer_ask.setVisibility(View.VISIBLE); 136 137 break; 138 139 } 140 } 141 142 /** 143 * 144 * @Title: loadData 145 * @Description: 请求数据(问题) 146 * @param 147 * @return void 148 * @throws 149 */ 150 private void loadData() { 151 152 lvNews_footer.setVisibility(View.VISIBLE); 153 154 // 请求我的问题 155 sendAskRequest(); 156 // 请求我的回答 157 sendAnswerRequest(); 158 } 159 160 /** 161 * 162 * @Title: sendAskRequest 163 * @Description: 发送请求(问题) 164 * @param 165 * @return void 166 * @throws 167 */ 168 private void sendAskRequest() { 169 RequestQueue queue = MyApp.getRequestQueue(); 170 171 int mid = LoginMessage.getUserId(); 172 int dateline = (int) (System.currentTimeMillis() / 1000); 173 StringRequest request = new StringRequest(Method.GET, ask_url 174 + "?size=" + RESULTS_PAGE_SIZE + "&start=" 175 + (adapter_ask.getCount() + 1) + "&mid=" + mid + "&dateline=" 176 + dateline, createMyReqSuccessListener(), 177 createMyReqErrorListener()); 178 queue.add(request); 179 } 180 181 /** 182 * 183 * @Title: loadDataAsk 184 * @Description: 请求数据(问题) 185 * @param 186 * @return void 187 * @throws 188 */ 189 private void loadDataAsk() { 190 lvNews_footer.setVisibility(View.VISIBLE); 191 192 sendAskRequest(); 193 } 194 195 /** 196 * 197 * @Title: loadDataAnswer 198 * @Description: 请求数据(回答) 199 * @param 200 * @return void 201 * @throws 202 */ 203 private void loadDataAnswer() { 204 205 lvNews_footer.setVisibility(View.VISIBLE); 206 lv_ask_answer.setAdapter(adapter_answer); 207 208 sendAnswerRequest(); 209 } 210 211 /** 212 * 213 * @Title: sendAnswerRequest 214 * @Description: 发送请求(回答) 215 * @param 216 * @return void 217 * @throws 218 */ 219 private void sendAnswerRequest() { 220 221 RequestQueue queue = MyApp.getRequestQueue(); 222 int replierid = LoginMessage.getUserId(); 223 int answertime = (int) (System.currentTimeMillis() / 1000); 224 StringRequest request = new StringRequest(Method.GET, answer_url 225 + "?size=" + RESULTS_PAGE_SIZE + "&start=" 226 + (adapter_answer.getCount() + 1) + "&replierid=" + replierid 227 + "&answertime=" + answertime, 228 createMyReqSuccessAnswerListener(), 229 createMyReqErrorAnswerListener()); 230 queue.add(request); 231 } 232 233 /** 234 * 235 * @Title: createMyReqSuccessListener 236 * @Description: 成功返回数据(问题) 237 * @param @return 238 * @return Response.Listener<String> 239 * @throws 240 */ 241 private Response.Listener<String> createMyReqSuccessListener() { 242 243 return new Response.Listener<String>() { 244 245 @Override 246 public void onResponse(String response) { 247 // 读取数据后要保存到本地数据库 248 Type listType = new TypeToken<List<PersonCenterAsk>>() { 249 }.getType(); 250 Gson gson = new Gson(); 251 List<PersonCenterAsk> listtemp = gson.fromJson(response, 252 listType); 253 254 if (listtemp.size() != 0) { 255 256 if (adapter_ask.getList() != null) { 257 adapter_ask.getList().addAll(listtemp); 258 } 259 adapter_ask.notifyDataSetChanged(); 260 261 } 262 lvNews_footer.setVisibility(View.INVISIBLE); 263 // 清理list 264 listtemp = null; 265 266 } 267 }; 268 269 } 270 271 /** 272 * 273 * @Title: createMyErrorListener 274 * @Description: 返回数据失败(问题) 275 * @param @return 276 * @return Response.ErrorListener 277 * @throws 278 */ 279 private Response.ErrorListener createMyReqErrorListener() { 280 return new Response.ErrorListener() { 281 @Override 282 public void onErrorResponse(VolleyError arg0) { 283 Toast.makeText(getActivity(), "请求数据失败", Toast.LENGTH_SHORT) 284 .show(); 285 } 286 }; 287 } 288 289 /** 290 * 291 * @Title: createMyReqSuccessAnswerListener 292 * @Description: 返回数据成功(回答) 293 * @param @return 294 * @return Response.Listener<String> 295 * @throws 296 */ 297 private Response.Listener<String> createMyReqSuccessAnswerListener() { 298 return new Response.Listener<String>() { 299 @Override 300 public void onResponse(String response) { 301 302 // 读取数据后要保存到本地数据库 303 Type listType = new TypeToken<List<PersonCenterAnswer>>() { 304 }.getType(); 305 Gson gson = new Gson(); 306 List<PersonCenterAnswer> list_answer = gson.fromJson(response, 307 listType); 308 if (list_answer.size() != 0) { 309 310 if (adapter_answer.getList() != null) { 311 adapter_answer.getList().addAll(list_answer); 312 } 313 adapter_answer.notifyDataSetChanged(); 314 } 315 lvNews_footer.setVisibility(View.INVISIBLE); 316 list_answer = null; 317 318 } 319 }; 320 } 321 322 /** 323 * 324 * @Title: createMyReqErrorAnswerListener 325 * @Description: 返回数据失败(回答) 326 * @param @return 327 * @return Response.ErrorListener 328 * @throws 329 */ 330 private Response.ErrorListener createMyReqErrorAnswerListener() { 331 return new Response.ErrorListener() { 332 @Override 333 public void onErrorResponse(VolleyError arg0) { 334 Toast.makeText(getActivity(), "请求数据失败", Toast.LENGTH_SHORT) 335 .show(); 336 } 337 }; 338 } 339 340 class AskonItemClickListener implements OnItemClickListener { 341 342 @Override 343 public void onItemClick(AdapterView<?> parent, View view, int position, 344 long id) { 345 346 PersonCenterAsk askanswer = adapter_ask.getItem(position); 347 String tidname = askanswer.getTidname(); 348 long asktime = 1000 * askanswer.getDateline(); 349 String question = askanswer.getTitle(); 350 String asker = askanswer.getUname(); 351 int questionid = askanswer.getQuestionid(); 352 int tid = askanswer.getTid(); 353 Intent intent = new Intent(getActivity(), AskListItemActivity.class); 354 intent.putExtra("title", asker); 355 intent.putExtra("index", "myask");// 标志位,表示是从问答界面的item跳转的 356 357 SharedPreferences.Editor editor = getActivity() 358 .getSharedPreferences("askanswerInfo", Context.MODE_PRIVATE) 359 .edit(); 360 editor.putString("asker", asker); 361 editor.putString("question", question); 362 editor.putLong("asktime", asktime); 363 editor.putInt("questionid", questionid); 364 editor.putString("tidname", tidname); 365 editor.putInt("tid", tid); 366 editor.commit(); 367 startActivity(intent); 368 369 } 370 371 } 372 373 class AnswerOnItemClickListener implements OnItemClickListener { 374 375 @Override 376 public void onItemClick(AdapterView<?> parent, View view, int position, 377 long id) { 378 PersonCenterAnswer answerask = adapter_answer.getItem(position); 379 String tidname = answerask.getTidname(); 380 long asktime = 1000 * answerask.getAsktime(); 381 String question = answerask.getTitle(); 382 String asker = answerask.getAsker(); 383 int questionid = answerask.getQuestionid(); 384 int tid = answerask.getTid(); 385 386 Intent intent = new Intent(getActivity(), AskListItemActivity.class); 387 intent.putExtra("title", asker); 388 intent.putExtra("index", "myanswer");// 标志位,表示是从问答界面的item跳转的 389 SharedPreferences.Editor editor = getActivity() 390 .getSharedPreferences("askanswerInfo", Context.MODE_PRIVATE) 391 .edit(); 392 editor.putString("asker", asker); 393 editor.putString("question", question); 394 editor.putLong("asktime", asktime); 395 editor.putInt("questionid", questionid); 396 editor.putString("tidname", tidname); 397 editor.putInt("tid", tid); 398 editor.commit(); 399 startActivity(intent); 400 401 } 402 } 403 404 /** 405 * 406 * @ClassName: EndScrollListener 407 * @Description: 下拉刷新(ask) 408 * @author ws 409 * @date 2014-2-11 下午4:43:38 410 * 411 */ 412 public class EndlessScrollListener implements OnScrollListener { 413 414 private boolean isLastRow = true; 415 416 public EndlessScrollListener() { 417 } 418 419 @Override 420 public void onScroll(AbsListView view, int firstVisibleItem, 421 int visibleItemCount, int totalItemCount) { 422 if (firstVisibleItem + visibleItemCount == totalItemCount 423 && totalItemCount > 0) { 424 isLastRow = true; 425 } 426 } 427 428 @Override 429 public void onScrollStateChanged(AbsListView view, int scrollState) { 430 if (isLastRow 431 && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { 432 isLastRow = false; 433 sendAskRequest(); 434 } 435 } 436 437 } 438 439 /** 440 * 441 * @ClassName: EndScrollListener 442 * @Description: 下拉刷新(answer) 443 * @author ws 444 * @date 2014-2-11 下午4:43:38 445 * 446 */ 447 public class EndlessAnswerScrollListener implements OnScrollListener { 448 449 private boolean isLastRow = true; 450 451 public EndlessAnswerScrollListener() { 452 } 453 454 @Override 455 public void onScroll(AbsListView view, int firstVisibleItem, 456 int visibleItemCount, int totalItemCount) { 457 if (firstVisibleItem + visibleItemCount == totalItemCount 458 && totalItemCount > 0) { 459 isLastRow = true; 460 } 461 } 462 463 @Override 464 public void onScrollStateChanged(AbsListView view, int scrollState) { 465 if (isLastRow 466 && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { 467 isLastRow = false; 468 sendAnswerRequest(); 469 } 470 } 471 472 } 473 474 @Override 475 public void onResume() { 476 super.onResume(); 477 StatService.onResume(this); 478 } 479 480 @Override 481 public void onPause() { 482 super.onPause(); 483 StatService.onPause(this); 484 } 485 486 }