• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps My listview items get repeat when it scrolls down . Please solve this issue!!

  1. // This is my JobListAdapter class

  2. package com.example.hellotest.adapters;

  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.List;
  6. import java.util.Locale;

  7. import android.content.Context;
  8. import android.view.LayoutInflater;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.widget.BaseAdapter;
  12. import android.widget.TextView;

  13. import com.example.hellotest.R;
  14. import com.example.hellotest.model.Job;

  15. public class JobListAdapter extends BaseAdapter {

  16. private LayoutInflater mInflater ;
  17. private List<Job> mJobs;
  18. private SimpleDateFormat mDateFormat;
  19. private SimpleDateFormat mInputFormat;
  20. private String mPosterPrefix;
  21. public JobListAdapter(Context context) {
  22. mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  23. mDateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
  24. mInputFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.US);
  25. mPosterPrefix = context.getString(R.string.job_posted_by);
  26. }
  27. public void setJobList(List<Job> jobs) {
  28. mJobs = jobs;
  29. }
  30. @override
  31. public int getCount() {
  32. if(null != mJobs) {
  33. //mJobs.clear();
  34. return mJobs.size();
  35. }
  36. return 0;
  37. }

  38. @override
  39. public Object getItem(int position) {
  40. return mJobs.get(position);
  41. }

  42. @override
  43. public long getItemId(int position) {
  44. return mJobs.get(position).getId();
  45. }
  46. // There might be some problem here in this function i googled it but doesnot find anything worth.
  47. @override
  48. public View getView(int position, View convertView, ViewGroup parent) {
  49. ViewHolder holder;
  50. if(null == convertView) {
  51. convertView = mInflater.inflate(R.layout.job_list_row, null);
  52. holder = new ViewHolder();
  53. holder.created = (TextView) convertView.findViewById(R.id.job_listing_date);
  54. holder.location = (TextView) convertView.findViewById(R.id.job_listing_location);
  55. holder.title = (TextView) convertView.findViewById(R.id.job_listing_title);
  56. holder.experience = (TextView) convertView.findViewById(R.id.job_listing_experience);
  57. holder.poster = (TextView) convertView.findViewById(R.id.job_listing_posted_by);
  58. convertView.setTag(holder);
  59. }
  60. else
  61. {
  62. holder = (ViewHolder) convertView.getTag();
  63. }
  64. updateRow(holder, mJobs.get(position));
  65. //notifyDataSetChanged();
  66. return convertView;
  67. }
  68. private void updateRow(ViewHolder holder, Job job) {
  69. holder.title.setText(job.getTitle());
  70. int id = job.isPremium() ? R.drawable.icon_premium : 0;
  71. holder.created.setText(getDate(job.getCreated()));
  72. holder.created.setCompoundDrawablesWithIntrinsicBounds(0, 0, id, 0);
  73. holder.experience.setText(job.getExperience());
  74. holder.location.setText(job.getLocation());
  75. holder.poster.setText(mPosterPrefix + job.getPoster());
  76. }

  77. private CharSequence getDate(String created) {
  78. try {
  79. return mDateFormat.format(mInputFormat.parse(created));
  80. } catch (ParseException e) {
  81. e.printStackTrace();
  82. }
  83. return created;
  84. }

  85. private static class ViewHolder {
  86. TextView created;
  87. TextView title;
  88. TextView location;
  89. TextView experience;
  90. TextView poster;
  91. }

  92. }

  93. //this is my JobListingFragment class

  94. package com.example.hellotest;
  95. import java.util.List;
  96. import android.app.Activity;
  97. import android.content.Intent;
  98. import android.os.Bundle;
  99. import android.support.v4.app.Fragment;
  100. import android.text.TextUtils;
  101. import android.view.LayoutInflater;
  102. import android.view.View;
  103. import android.view.View.OnClickListener;
  104. import android.view.ViewGroup;
  105. import android.widget.AbsListView;
  106. import android.widget.AbsListView.OnScrollListener;
  107. import android.widget.AdapterView;
  108. import android.widget.AdapterView.OnItemClickListener;
  109. import android.widget.ListView;
  110. import android.widget.ProgressBar;
  111. import android.widget.TextView;
  112. import android.widget.Toast;
  113. import com.android.volley.Request.Method;
  114. import com.android.volley.RequestQueue;
  115. import com.android.volley.Response;
  116. import com.android.volley.Response.ErrorListener;
  117. import com.android.volley.Response.Listener;
  118. import com.android.volley.VolleyError;
  119. import com.android.volley.toolbox.Volley;
  120. import com.example.hellotest.R;
  121. import com.example.hellotest.adapters.JobListAdapter;
  122. import com.example.hellotest.config.Constant;
  123. import com.example.hellotest.io.CookieStringRequest;
  124. import com.example.hellotest.io.json.JobsProcessor;
  125. import com.example.hellotest.model.Job;
  126. import com.example.hellotest.model.JobList;
  127. import com.example.hellotest.model.Pagination;
  128. import com.example.hellotest.tasks.JsonParserTask;
  129. import com.example.hellotest.tasks.JsonParsingListener;
  130. import com.example.hellotest.util.AccountUtils;
  131. import com.example.hellotest.util.Log;

  132. public class JobListingFragment extends Fragment {

  133. public static final String ARG_URL = "argument_url";
  134. public static final String ARG_IS_FILTER_ON = "argument_is_filtered";
  135. public static final String ARG_IS_DEFAULT_JOB_LIST = "argument_is_default_job_list";
  136. public static final String ARG_EMPTY_MESSAGE = "argument_empty_message";

  137. protected static final int REQUEST_EXPERIENCE = 0x11;
  138. protected static final int REQUEST_LOCATION = 0x12;
  139. private ListView mJobsList;
  140. private TextView mMessageView;
  141. private JobListAdapter mAdapter;
  142. private List<Job> mJobs;
  143. private Pagination mPagination;
  144. private boolean mIsFetching;
  145. private boolean mIsDefaultList;
  146. private boolean mIsFilterOn;
  147. private String mUrl;
  148. private String mLocId;
  149. private int mExperienceId = -1;
  150. private ProgressBar mFooterProgress;
  151. private Log mLogger = new Log(JobListingFragment.class);
  152. private Object mRequestTag = new Object();
  153. private RequestQueue mRequestQueue;

  154. @override
  155. public void onCreate(Bundle savedInstanceState) {
  156. super.onCreate(savedInstanceState);
  157. mAdapter = new JobListAdapter(getActivity());
  158. if (null != savedInstanceState) {
  159. getState(savedInstanceState);
  160. } else {
  161. getState(getArguments());
  162. }
  163. // init();
  164. }
  165. @override
  166. public void onAttach(Activity activity) {
  167. super.onAttach(activity);
  168. mRequestQueue = Volley.newRequestQueue(getActivity());
  169. }
  170. @override
  171. public void onDetach() {
  172. mRequestQueue.cancelAll(mRequestTag);
  173. super.onDetach();
  174. }
  175. @override
  176. public void onResume() {
  177. init();
  178. super.onResume();
  179. }

  180. private void getState(Bundle bundle) {
  181. mUrl = bundle.getString(ARG_URL);
  182. mIsFilterOn = bundle.getBoolean(ARG_IS_FILTER_ON);
  183. mIsDefaultList = bundle.getBoolean(ARG_IS_DEFAULT_JOB_LIST);
  184. }

  185. @override
  186. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  187. {
  188. View view = inflater.inflate(R.layout.fragment_job_listing, null);
  189. mJobsList = (ListView) view.findViewById(R.id.job_list);
  190. mMessageView = (TextView) view.findViewById(R.id.job_listing_message);
  191. return view;
  192. }

  193. @override
  194. public void onViewCreated(View view, Bundle savedInstanceState) {
  195. View footer = getLayoutInflater(savedInstanceState).inflate(R.layout.paginated_list_footer, null);
  196. mFooterProgress = (ProgressBar) footer.findViewById(R.id.footer_progress);
  197. if (!mIsFilterOn) {
  198. view.findViewById(R.id.job_listing_filter_container).setVisibility(View.GONE);
  199. } else {
  200. view.findViewById(R.id.job_listing_experience).setOnClickListener(mOnClickListener);
  201. view.findViewById(R.id.job_listing_location).setOnClickListener(mOnClickListener);
  202. }
  203. mJobsList.addFooterView(footer);
  204. mJobsList.setAdapter(mAdapter);
  205. mJobsList.setOnScrollListener(mOnScrollListener);
  206. mJobsList.setOnItemClickListener(mOnItemClickListener);
  207. super.onViewCreated(view, savedInstanceState);
  208. }

  209. @override
  210. public void onSaveInstanceState(Bundle outState) {
  211. outState.putString(ARG_URL, mUrl);
  212. outState.putBoolean(ARG_IS_FILTER_ON, mIsFilterOn);
  213. outState.putBoolean(ARG_IS_DEFAULT_JOB_LIST, mIsDefaultList);
  214. super.onSaveInstanceState(outState);
  215. }

  216. public void startAfresh(String url, boolean isPaginated) {
  217. mLogger.d("old fragment reused");
  218. mIsFilterOn = true;
  219. mUrl = url;
  220. reset();
  221. init();
  222. }

  223. private void init() {
  224. mLocId = AccountUtils.getLocationFilter();
  225. mExperienceId = AccountUtils.getExperienceFilter();
  226. String url = getUrl(1);
  227. fetchJobs(url);
  228. }

  229. private void reset() {
  230. mJobs = null;
  231. mPagination = null;
  232. mAdapter.setJobList(null);
  233. mAdapter.notifyDataSetChanged();
  234. }

  235. private String getUrl(int pageNumber) {
  236. String appender = "";
  237. if (mIsFilterOn) {
  238. if (null != mLocId || -1 < mExperienceId) {
  239. if (null != mLocId) {
  240. appender += "/loc-" + mLocId;
  241. } else {
  242. appender += "/loc-" + 0;
  243. }

  244. if (-1 < mExperienceId) {
  245. appender += "/exp-" + mExperienceId;
  246. } else {
  247. appender += "/exp-" + 0;
  248. }
  249. }
  250. }
  251. String url = mUrl + appender + "/pg-" + pageNumber;
  252. if (mIsDefaultList && AccountUtils.isLoggedIn()) {
  253. url += "?" + Constant.MAP_COOKIE_KEY + "=" + AccountUtils.getCookie();
  254. }
  255. return url;
  256. }

  257. private void fetchJobs(String url) {
  258. mIsFetching = true;
  259. mLogger.d("url :" + url);
  260. int method = mIsDefaultList ? Method.GET : Method.POST;
  261. CookieStringRequest request = new CookieStringRequest(method, url, mListener, mErrorListener);
  262. request.setTag(mRequestTag);
  263. mRequestQueue.add(request);
  264. }

  265. private Response.Listener<String> mListener = new Listener<String>() {

  266. @override
  267. public void onResponse(String response) {
  268. mLogger.d("response :" + response);
  269. JsonParserTask<JobList> jsonTask = new JsonParserTask<JobList>(new JobsProcessor());
  270. jsonTask.setListener(mJsonListener);
  271. jsonTask.execute(response);

  272. }
  273. };

  274. private Response.ErrorListener mErrorListener = new ErrorListener() {

  275. @override
  276. public void onErrorResponse(VolleyError error) {
  277. mIsFetching = false;
  278. Toast.makeText(getActivity(), R.string.network_error, Toast.LENGTH_LONG).show();
  279. }
  280. };

  281. private JsonParsingListener<JobList> mJsonListener = new JsonParsingListener<JobList>() {

  282. @override
  283. public void onSuccess(JobList result) {
  284. if (null == mPagination) {
  285. mPagination = result.getPagination();
  286. mPagination.setCurrentPage(0);
  287. if(null == result.getJobs() || 0 == result.getJobs().size()) {
  288. mMessageView.setText(getArguments().getString(ARG_EMPTY_MESSAGE));
  289. mMessageView.setVisibility(View.VISIBLE);
  290. } else {
  291. mMessageView.setVisibility(View.GONE);
  292. }
  293. } else {
  294. mPagination.updateData(result.getPagination());
  295. }

  296. if (null != mJobs) {
  297. //mJobs.add(result.)
  298. //mJobs.clear();
  299. mJobs.retainAll(mJobs);
  300. mJobs.addAll(result.getJobs());
  301. //mJobs.clear();
  302. } else {
  303. mJobs = result.getJobs();
  304. }
  305. mAdapter.setJobList(mJobs);
  306. mAdapter.notifyDataSetChanged();
  307. mIsFetching = false;
  308. }

  309. @override
  310. public void onFailure(Exception e) {
  311. Toast.makeText(getActivity(), "Unable to process response", Toast.LENGTH_LONG).show();
  312. mIsFetching = false;
  313. }
  314. };

  315. private OnItemClickListener mOnItemClickListener = new OnItemClickListener() {

  316. @override
  317. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  318. Job job = (Job) mAdapter.getItem(position);
  319. Intent intent = new Intent(getActivity(), JobDetailsActivity.class);
  320. intent.putExtra(JobDetailsActivity.EXTRA_JOB, job);
  321. startActivity(intent);
  322. }
  323. };
  324. // this function may have some biug because when i scrolls down the list repeats . please suggest the solution
  325. private OnScrollListener mOnScrollListener = new OnScrollListener() {

  326. @override
  327. public void onScrollStateChanged(AbsListView view, int scrollState) {

  328. }

  329. @override
  330. public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  331. boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
  332. if (loadMore && totalItemCount > 0 && null != mPagination) {
  333. boolean isLastPage = mPagination.getCurrentPage() >= mPagination.getTotalPages();
  334. if (isLastPage) {
  335. mFooterProgress.setVisibility(View.GONE);
  336. }
  337. if (!mIsFetching && !isLastPage) {
  338. fetchJobs(getUrl(mPagination.getCurrentPage()+1));
  339. }
  340. }
  341. }
  342. };

  343. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  344. if (Activity.RESULT_OK == resultCode) {
  345. switch (requestCode) {
  346. case REQUEST_EXPERIENCE:
  347. onExperienceSelection(data);
  348. break;

  349. case REQUEST_LOCATION:
  350. onLocationSelection(data);
  351. break;
  352. }
  353. }
  354. }

  355. private void onLocationSelection(Intent data) {
  356. int ids[] = data.getIntArrayExtra(PopupActivity.RESULT_ID);
  357. String idStrs = "";
  358. for (int id : ids) {
  359. idStrs += "_" + id;
  360. }
  361. if (TextUtils.isEmpty(idStrs)) {
  362. mLocId = null;
  363. } else {
  364. mLocId = idStrs.substring(1);
  365. }
  366. AccountUtils.setLocationFilter(mLocId);
  367. reset();
  368. fetchJobs(getUrl(1));

  369. }

  370. private void onExperienceSelection(Intent data) {
  371. mExperienceId = data.getIntExtra(PopupActivity.RESULT_ID, -1);
  372. AccountUtils.setExperienceFilter(mExperienceId);
  373. mLogger.d("experince id :" + mExperienceId);
  374. reset();
  375. fetchJobs(getUrl(1));
  376. };

  377. private OnClickListener mOnClickListener = new OnClickListener() {

  378. @override
  379. public void onClick(View v) {
  380. Intent intent = new Intent(getActivity(), PopupActivity.class);
  381. switch (v.getId()) {
  382. case R.id.job_listing_experience:
  383. intent.putExtra(PopupActivity.EXTRA_DATA_TYPE, PopupActivity.DATA_TYPE_FILTER_EXPERIENCE);
  384. intent.putExtra(PopupActivity.EXTRA_SELECTED_ID, mExperienceId);
  385. startActivityForResult(intent, REQUEST_EXPERIENCE);
  386. break;

  387. case R.id.job_listing_location:
  388. intent.putExtra(PopupActivity.EXTRA_DATA_TYPE, PopupActivity.DATA_TYPE_FILTER_LOCATION);
  389. intent.putExtra(PopupActivity.EXTRA_IS_MULTIPLE_MODE_ON, true);
  390. passLocationIds(intent);
  391. startActivityForResult(intent, REQUEST_LOCATION);
  392. break;
  393. }

  394. }
  395. };

  396. protected void passLocationIds(Intent intent) {
  397. if(null != mLocId) {
  398. String[] str = mLocId.split("_");
  399. int ids[] = new int[str.length];
  400. for(int i = 0; i < str.length; i++) {
  401. ids = Integer.parseInt(str.trim());
    [*] }
    [*] intent.putExtra(PopupActivity.EXTRA_SELECTED_ID, ids);
    [*] }
    [*]
    [*] }
    [*]}
 
Back
Top Bottom